[{"data":1,"prerenderedAt":10989},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord":3,"content-page-quiz:none":532,"book-module-total-pages":533,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":534,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord":10988},{"id":4,"title":5,"audience":6,"body":7,"contentType":505,"course":506,"description":507,"estimateBasis":508,"estimatedDiscussionMinutes":509,"estimatedLiveMinutes":510,"estimatedTotalMinutes":511,"extension":512,"meta":513,"module":514,"navigation":515,"order":516,"path":517,"promptAssist":518,"seo":519,"status":520,"stem":521,"tags":522,"videoDuration":527,"videoId":528,"videoLink":529,"videoTitle":530,"week":514,"__hash__":531},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord","student",{"type":8,"value":9,"toc":488},"minimark",[10,52,92,145,195,243,277,339,381,431,460],[11,12,15,20,36],"slide",{"id":13,"level":14},"learn-courses-flow","2",[16,17,19],"h2",{"id":18},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[21,22,23,27,30,33],"ul",{},[24,25,26],"li",{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[24,28,29],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[24,31,32],{},"The goal is to keep tasks clear and objective for students and grading",[24,34,35],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[37,38,39,40,46,47,51],"p",{},"NOTE: Summer 2026 the previous Learn Platform (",[41,42,43],"a",{"href":43,"rel":44},"https:\u002F\u002Flearn.ethereallab.app",[45],"nofollow",") has been replaced by Learn Courses Platform (",[41,48,49],{"href":49,"rel":50},"https:\u002F\u002Fcourses.ethereallab.app",[45],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,53,55,58,61,89],{"id":54,"level":14},"learn-courses-title",[16,56,5],{"id":57},"learn-courses-platform-and-discord",[37,59,60],{},"How to join:",[21,62,63,69,77,80,83,86],{},[24,64,65,66],{},"Visit the platform ",[41,67,49],{"href":49,"rel":68},[45],[24,70,71,72],{},"Sign in with your NJIT email\n",[21,73,74],{},[24,75,76],{},"If you're in the Canvas course, you should automatically get synced to this platform",[24,78,79],{},"Visit your Profile page",[24,81,82],{},"Associate your Discord account",[24,84,85],{},"Join the course Discord server",[24,87,88],{},"Verify that your course channels appear on Discord",[37,90,91],{},"You can follow the steps on the below slides for guidance",[11,93,96,99],{"id":94,"level":95},"visit-learn-courses","3",[16,97,98],{"id":94},"Visit Learn Courses",[100,101,104,135],"two-col",{"gap":102,"left-width":103,"right-width":103},"lg","1fr",[105,106,108,111,116],"template",{"v-slot:left":107},"",[37,109,110],{},"Go to:",[37,112,113],{},[41,114,49],{"href":49,"rel":115},[45],[21,117,118,126,129,132],{},[24,119,120,121,125],{},"Click the ",[122,123,124],"strong",{},"Login"," button",[24,127,128],{},"Use your NJIT email",[24,130,131],{},"Only NJIT accounts are allowed",[24,133,134],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[105,136,137],{"v-slot:right":107},[37,138,139],{},[140,141],"img",{"alt":142,"src":143,"variant":144},"Learn Courses logged-out home page with the Login button visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fhome-loggedout-login-button.png","sidecar-screenshot",[11,146,148,151],{"id":147,"level":95},"associate-discord-name",[16,149,150],{"id":147},"Associate Discord Name",[100,152,153,179],{"gap":102,"left-width":103,"right-width":103},[105,154,155,158,176],{"v-slot:left":107},[37,156,157],{},"On Learn Courses:",[159,160,161,164,170,173],"ol",{},[24,162,163],{},"Open your Profile",[24,165,166,167],{},"Click ",[122,168,169],{},"Refresh Discord Username",[24,171,172],{},"Authorize the Discord prompt",[24,174,175],{},"After the success message appears, save your profile",[37,177,178],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[105,180,181,188],{"v-slot:right":107},[37,182,183],{},[140,184],{"alt":185,"src":186,"variant":144,"max-height":187},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[37,189,190],{},[140,191],{"alt":192,"src":193,"variant":144,"max-height":194},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,196,198,201],{"id":197,"level":95},"authorize-discord",[16,199,200],{"id":197},"Authorize Discord",[100,202,203,227],{"gap":102,"left-width":103,"right-width":103},[105,204,205,208],{"v-slot:left":107},[37,206,207],{},"Discord will ask whether Learn Courses can access your Discord account.",[21,209,210,213,218,221,224],{},[24,211,212],{},"Confirm you are signed in to the correct Discord account",[24,214,166,215],{},[122,216,217],{},"Authorize",[24,219,220],{},"Return to Learn Courses",[24,222,223],{},"Look for the success message",[24,225,226],{},"Save the profile change",[105,228,229,236],{"v-slot:right":107},[37,230,231],{},[140,232],{"alt":233,"src":234,"variant":144,"max-height":235},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[37,237,238],{},[140,239],{"alt":240,"src":241,"variant":144,"max-height":242},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,244,246,249,252,258,266],{"id":245,"level":95},"join-the-channel",[16,247,248],{"id":245},"Join The Channel",[37,250,251],{},"Use the Discord link provided on Canvas, or use:",[37,253,254],{},[41,255,256],{"href":256,"rel":257},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[45],[37,259,260,261,265],{},"This should send you to the ",[262,263,264],"code",{},"access-channel"," channel.",[21,267,268,271,274],{},[24,269,270],{},"Other channels are protected by a bot",[24,272,273],{},"Messages may be blocked until your name and role are set",[24,275,276],{},"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,278,280,283],{"id":279,"level":14},"verify-with-quackbot",[16,281,282],{"id":279},"Verify With QuackBot",[100,284,285,330],{"gap":102,"left-width":103,"right-width":103},[105,286,287,299,305,310,313,327],{"v-slot:left":107},[21,288,289,292],{},[24,290,291],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[24,293,294,295,298],{},"If you don't see the proper semester category (i.e., ",[262,296,297],{},"summer-2026",") or the expected channels you can do the below action",[37,300,301,302,304],{},"In ",[262,303,264],{},", enter:",[37,306,307],{},[262,308,309],{},"@QuackBot",[37,311,312],{},"QuackBot will:",[21,314,315,318,321,324],{},[24,316,317],{},"Verify your account",[24,319,320],{},"Pull in your name and section",[24,322,323],{},"Apply your class role",[24,325,326],{},"Update your server nickname",[37,328,329],{},"This does not change your real Discord username.",[105,331,332],{"v-slot:right":107},[37,333,334],{},[140,335],{"alt":336,"src":337,"variant":144,"max-height":338},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,340,342,346,349,360,365],{"id":341,"level":14},"welcome-and-potential-issues",[16,343,345],{"id":344},"welcome","Welcome",[37,347,348],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[21,350,351,354,357],{},[24,352,353],{},"It should appear after the general channels",[24,355,356],{},"It should include one or more channels for your active courses",[24,358,359],{},"Use the correct course channel for class questions and discussion",[361,362,364],"h3",{"id":363},"potential-issues","Potential Issues",[21,366,367,370],{},[24,368,369],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[24,371,372,373,376],{},"If there is an issue, email the instructor or DM ",[262,374,375],{},"MattToegel",[21,377,378],{},[24,379,380],{},"Some Discord privacy settings may require a friend request before DMs work",[11,382,384,387],{"id":383,"level":14},"general-conduct",[16,385,386],{"id":383},"General Conduct",[21,388,389,392,395,406,409,417,425,428],{},[24,390,391],{},"Use class-related channels for questions and discussion",[24,393,394],{},"Ask general course questions in the channel instead of DM when possible",[24,396,397,398],{},"Do not post screenshots of in-progress assignment solutions\n",[21,399,400,403],{},[24,401,402],{},"This would be more ideal for a DM",[24,404,405],{},"If you see posted solution-like items don't assume they're correct",[24,407,408],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[24,410,411,412],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[21,413,414],{},[24,415,416],{},"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",[24,418,419,420],{},"Keep off-topic items out of class channels\n",[21,421,422],{},[24,423,424],{},"There are plenty of categorized channels to use and I can always make more",[24,426,427],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[24,429,430],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,432,434,437,440],{"id":433,"level":14},"quick-check",[16,435,436],{"id":433},"Quick Check",[37,438,439],{},"Before continuing, confirm:",[21,441,442,445,448,451,454,457],{},[24,443,444],{},"You can sign in to Learn Courses with your NJIT email",[24,446,447],{},"Your profile is saved",[24,449,450],{},"Discord is associated with your Learn Courses profile",[24,452,453],{},"You joined the Discord server",[24,455,456],{},"QuackBot applied your course role",[24,458,459],{},"You can see the correct course channel",[11,461,463,466],{"id":462,"level":14},"summary",[16,464,465],{"id":462},"Summary",[21,467,468,471,479,482,485],{},[24,469,470],{},"Learn Courses supports course tools and course-specific setup",[24,472,473,474],{},"Canvas remains the official assignment, grade, and course hub\n",[21,475,476],{},[24,477,478],{},"All necessary items will be linked on Canvas",[24,480,481],{},"Discord is the preferred quick communication channel",[24,483,484],{},"QuackBot connects your Discord account to the correct course role",[24,486,487],{},"Good course communication keeps help requests specific and protects private information",{"title":107,"searchDepth":489,"depth":489,"links":490},2,[491,492,493,494,495,496,497,498,502,503,504],{"id":18,"depth":489,"text":19},{"id":57,"depth":489,"text":5},{"id":94,"depth":489,"text":98},{"id":147,"depth":489,"text":150},{"id":197,"depth":489,"text":200},{"id":245,"depth":489,"text":248},{"id":279,"depth":489,"text":282},{"id":344,"depth":489,"text":345,"children":499},[500],{"id":363,"depth":501,"text":364},3,{"id":383,"depth":489,"text":386},{"id":433,"depth":489,"text":436},{"id":462,"depth":489,"text":465},"presentation","Internet Applications","Set up Learn Courses Platform and Discord before starting terminal, Git, and local server work.","Face-to-face class of about 40 students; includes account sign-in, Discord association, QuackBot role setup, and communication expectations.","10","20","30","md",{},"1",true,"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",false,{"title":5,"description":507},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[523,524,525,526],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",null,[],[535,879,1959,2848,3944,4883,5674,6741,7467,8292],{"id":4,"title":5,"audience":6,"body":536,"contentType":505,"course":506,"description":507,"estimateBasis":508,"estimatedDiscussionMinutes":509,"estimatedLiveMinutes":510,"estimatedTotalMinutes":511,"extension":512,"meta":876,"module":514,"navigation":515,"order":516,"path":517,"promptAssist":518,"seo":877,"status":520,"stem":521,"tags":878,"videoDuration":527,"videoId":528,"videoLink":529,"videoTitle":530,"week":514,"__hash__":531},{"type":8,"value":537,"toc":861},[538,560,589,622,656,690,713,757,785,821,841],[11,539,540,542,552],{"id":13,"level":14},[16,541,19],{"id":18},[21,543,544,546,548,550],{},[24,545,26],{},[24,547,29],{},[24,549,32],{},[24,551,35],{},[37,553,39,554,46,557,51],{},[41,555,43],{"href":43,"rel":556},[45],[41,558,49],{"href":49,"rel":559},[45],[11,561,562,564,566,587],{"id":54,"level":14},[16,563,5],{"id":57},[37,565,60],{},[21,567,568,573,579,581,583,585],{},[24,569,65,570],{},[41,571,49],{"href":49,"rel":572},[45],[24,574,71,575],{},[21,576,577],{},[24,578,76],{},[24,580,79],{},[24,582,82],{},[24,584,85],{},[24,586,88],{},[37,588,91],{},[11,590,591,593],{"id":94,"level":95},[16,592,98],{"id":94},[100,594,595,616],{"gap":102,"left-width":103,"right-width":103},[105,596,597,599,604],{"v-slot:left":107},[37,598,110],{},[37,600,601],{},[41,602,49],{"href":49,"rel":603},[45],[21,605,606,610,612,614],{},[24,607,120,608,125],{},[122,609,124],{},[24,611,128],{},[24,613,131],{},[24,615,134],{},[105,617,618],{"v-slot:right":107},[37,619,620],{},[140,621],{"alt":142,"src":143,"variant":144},[11,623,624,626],{"id":147,"level":95},[16,625,150],{"id":147},[100,627,628,646],{"gap":102,"left-width":103,"right-width":103},[105,629,630,632,644],{"v-slot:left":107},[37,631,157],{},[159,633,634,636,640,642],{},[24,635,163],{},[24,637,166,638],{},[122,639,169],{},[24,641,172],{},[24,643,175],{},[37,645,178],{},[105,647,648,652],{"v-slot:right":107},[37,649,650],{},[140,651],{"alt":185,"src":186,"variant":144,"max-height":187},[37,653,654],{},[140,655],{"alt":192,"src":193,"variant":144,"max-height":194},[11,657,658,660],{"id":197,"level":95},[16,659,200],{"id":197},[100,661,662,680],{"gap":102,"left-width":103,"right-width":103},[105,663,664,666],{"v-slot:left":107},[37,665,207],{},[21,667,668,670,674,676,678],{},[24,669,212],{},[24,671,166,672],{},[122,673,217],{},[24,675,220],{},[24,677,223],{},[24,679,226],{},[105,681,682,686],{"v-slot:right":107},[37,683,684],{},[140,685],{"alt":233,"src":234,"variant":144,"max-height":235},[37,687,688],{},[140,689],{"alt":240,"src":241,"variant":144,"max-height":242},[11,691,692,694,696,701,705],{"id":245,"level":95},[16,693,248],{"id":245},[37,695,251],{},[37,697,698],{},[41,699,256],{"href":256,"rel":700},[45],[37,702,260,703,265],{},[262,704,264],{},[21,706,707,709,711],{},[24,708,270],{},[24,710,273],{},[24,712,276],{},[11,714,715,717],{"id":279,"level":14},[16,716,282],{"id":279},[100,718,719,751],{"gap":102,"left-width":103,"right-width":103},[105,720,721,729,733,737,739,749],{"v-slot:left":107},[21,722,723,725],{},[24,724,291],{},[24,726,294,727,298],{},[262,728,297],{},[37,730,301,731,304],{},[262,732,264],{},[37,734,735],{},[262,736,309],{},[37,738,312],{},[21,740,741,743,745,747],{},[24,742,317],{},[24,744,320],{},[24,746,323],{},[24,748,326],{},[37,750,329],{},[105,752,753],{"v-slot:right":107},[37,754,755],{},[140,756],{"alt":336,"src":337,"variant":144,"max-height":338},[11,758,759,761,763,771,773],{"id":341,"level":14},[16,760,345],{"id":344},[37,762,348],{},[21,764,765,767,769],{},[24,766,353],{},[24,768,356],{},[24,770,359],{},[361,772,364],{"id":363},[21,774,775,777],{},[24,776,369],{},[24,778,372,779,781],{},[262,780,375],{},[21,782,783],{},[24,784,380],{},[11,786,787,789],{"id":383,"level":14},[16,788,386],{"id":383},[21,790,791,793,795,803,805,811,817,819],{},[24,792,391],{},[24,794,394],{},[24,796,397,797],{},[21,798,799,801],{},[24,800,402],{},[24,802,405],{},[24,804,408],{},[24,806,411,807],{},[21,808,809],{},[24,810,416],{},[24,812,419,813],{},[21,814,815],{},[24,816,424],{},[24,818,427],{},[24,820,430],{},[11,822,823,825,827],{"id":433,"level":14},[16,824,436],{"id":433},[37,826,439],{},[21,828,829,831,833,835,837,839],{},[24,830,444],{},[24,832,447],{},[24,834,450],{},[24,836,453],{},[24,838,456],{},[24,840,459],{},[11,842,843,845],{"id":462,"level":14},[16,844,465],{"id":462},[21,846,847,849,855,857,859],{},[24,848,470],{},[24,850,473,851],{},[21,852,853],{},[24,854,478],{},[24,856,481],{},[24,858,484],{},[24,860,487],{},{"title":107,"searchDepth":489,"depth":489,"links":862},[863,864,865,866,867,868,869,870,873,874,875],{"id":18,"depth":489,"text":19},{"id":57,"depth":489,"text":5},{"id":94,"depth":489,"text":98},{"id":147,"depth":489,"text":150},{"id":197,"depth":489,"text":200},{"id":245,"depth":489,"text":248},{"id":279,"depth":489,"text":282},{"id":344,"depth":489,"text":345,"children":871},[872],{"id":363,"depth":501,"text":364},{"id":383,"depth":489,"text":386},{"id":433,"depth":489,"text":436},{"id":462,"depth":489,"text":465},{},{"title":5,"description":507},[523,524,525,526],{"id":880,"title":881,"audience":6,"body":882,"contentType":505,"course":506,"description":1943,"estimateBasis":1944,"estimatedDiscussionMinutes":509,"estimatedLiveMinutes":1945,"estimatedTotalMinutes":1946,"extension":512,"meta":1947,"module":514,"navigation":515,"order":509,"path":1948,"promptAssist":518,"seo":1949,"status":520,"stem":1950,"tags":1951,"videoDuration":1955,"videoId":1956,"videoLink":1957,"videoTitle":881,"week":514,"__hash__":1958},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":883,"toc":1909},[884,942,979,1011,1073,1140,1191,1217,1237,1275,1303,1324,1359,1381,1453,1476,1521,1584,1636,1664,1684,1713,1753,1783,1793,1862],[11,885,887,891],{"id":886,"level":14},"why-cli-first",[16,888,890],{"id":889},"why-cli-comes-first","Why CLI Comes First",[21,892,893,901,909,923,931],{},[24,894,895,896],{},"Common language for setup and developer tools\n",[21,897,898],{},[24,899,900],{},"Git, servers, package installs, deployment logs",[24,902,903,904],{},"Works when there is no full desktop\n",[21,905,906],{},[24,907,908],{},"SSH, Ubuntu Server, minimal system access",[24,910,911,912],{},"Direct check of what the computer sees\n",[21,913,914,917,920],{},[24,915,916],{},"Current folder",[24,918,919],{},"Files and permissions",[24,921,922],{},"Command output",[24,924,925,926],{},"Repeatable steps beat guessing through menus\n",[21,927,928],{},[24,929,930],{},"Run a command, read output, adjust",[24,932,933,934],{},"Location still matters\n",[21,935,936,939],{},[24,937,938],{},"Wrong folder can make correct commands fail",[24,940,941],{},"Or create files in the wrong place",[11,943,945,948,951],{"id":944,"level":14},"goal",[16,946,947],{"id":944},"Goal",[37,949,950],{},"Build the command-line habits that make setup work predictable:",[21,952,953,956,959,973,976],{},[24,954,955],{},"Know what folder the terminal is using",[24,957,958],{},"Read file and folder lists before moving",[24,960,961,962,965,966,969,970],{},"Recognize common flags like ",[262,963,964],{},"-a",", ",[262,967,968],{},"-r",", and ",[262,971,972],{},"-l",[24,974,975],{},"Make small file changes and verify them",[24,977,978],{},"Stop safely when output does not match the lesson",[11,980,982,985,988,1008],{"id":981,"level":14},"before-you-start",[16,983,984],{"id":981},"Before You Start",[37,986,987],{},"Run these commands on your host computer",[21,989,990,1002,1005],{},[24,991,992,993],{},"Windows: Git Bash",[21,994,995],{},[24,996,997,998],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[41,999,1001],{"href":1000},"\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",[24,1003,1004],{},"Apple macOS: Terminal",[24,1006,1007],{},"Linux: Terminal",[37,1009,1010],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1012,1014,1018],{"id":1013,"level":14},"working-directory",[16,1015,1017],{"id":1016},"the-main-idea","The Main Idea",[21,1019,1020,1031,1042,1065],{},[24,1021,1022,1023],{},"Terminal commands run from one folder at a time\n",[21,1024,1025],{},[24,1026,1027,1028],{},"That folder is the ",[122,1029,1030],{},"working directory",[24,1032,1033,1036,1037],{},[262,1034,1035],{},"pwd",": print working directory\n",[21,1038,1039],{},[24,1040,1041],{},"Shows the full path to the folder your terminal is using",[24,1043,1044,1045],{},"Fresh terminal usually starts in your home folder\n",[21,1046,1047,1053,1059],{},[24,1048,1049,1050],{},"Windows Git Bash: ",[262,1051,1052],{},"\u002Fc\u002FUsers\u002Fyour-username",[24,1054,1055,1056],{},"Apple macOS: ",[262,1057,1058],{},"\u002FUsers\u002Fyour-username",[24,1060,1061,1062],{},"Linux: ",[262,1063,1064],{},"\u002Fhome\u002Fyour-username",[24,1066,1067,1068],{},"Commands from this lesson start from the working directory\n",[21,1069,1070],{},[24,1071,1072],{},"Unless you give a different path",[11,1074,1076,1079,1082,1134],{"id":1075,"level":14},"paths-relative-and-absolute",[16,1077,1078],{"id":1075},"Paths: Relative And Absolute",[37,1080,1081],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[21,1083,1084,1090,1096,1102,1128],{},[24,1085,1086,1087],{},"Relative path: starts from the working directory, like ",[262,1088,1089],{},"public\u002Findex.php",[24,1091,1092,1093],{},"Absolute path: starts from the system root, like ",[262,1094,1095],{},"\u002Fhome\u002Fstudent\u002Fproject",[24,1097,1098,1101],{},[262,1099,1100],{},"."," means the current folder",[24,1103,1104,1107,1108],{},[262,1105,1106],{},".."," means the parent folder\n",[21,1109,1110,1116,1122],{},[24,1111,1112,1115],{},[262,1113,1114],{},"..\u002F.."," goes up two folders",[24,1117,1118,1119],{},"Example: ",[262,1120,1121],{},"cd ..\u002F..",[24,1123,1124,1127],{},[262,1125,1126],{},"..."," is not a shortcut",[24,1129,1130,1133],{},[262,1131,1132],{},"~"," means your home folder",[37,1135,1136,1137,1139],{},"If a command affects the wrong place, check ",[262,1138,1035],{}," first, then check the path you typed",[11,1141,1143,1146,1149,1168,1171],{"id":1142,"level":14},"flags-options-and-arguments",[16,1144,1145],{"id":1142},"Flags, Options, And Arguments",[37,1147,1148],{},"Commands usually follow this shape:",[21,1150,1151,1157,1162],{},[24,1152,1153,1154],{},"Command: what to do, like ",[262,1155,1156],{},"ls",[24,1158,1159,1160],{},"Flag or option: how to do it, like ",[262,1161,964],{},[24,1163,1164,1165],{},"Argument: what to do it to, like ",[262,1166,1167],{},"public_html",[37,1169,1170],{},"Examples:",[21,1172,1173,1179,1185],{},[24,1174,1175,1178],{},[262,1176,1177],{},"ls -a"," shows hidden files",[24,1180,1181,1184],{},[262,1182,1183],{},"cp -r folder backup-folder"," copies a folder",[24,1186,1187,1190],{},[262,1188,1189],{},"nano -l file.txt"," opens with line numbers",[11,1192,1194,1198,1201,1212],{"id":1193,"level":14},"practice-loop",[16,1195,1197],{"id":1196},"practice-1-location-and-paths","Practice 1: Location And Paths",[37,1199,1200],{},"For each command, use the same pattern:",[159,1202,1203,1206,1209],{},[24,1204,1205],{},"Run one command",[24,1207,1208],{},"Read the output",[24,1210,1211],{},"Confirm the folder or file changed the way you expected",[21,1213,1214],{},[24,1215,1216],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1218,1220,1223,1226,1231,1234],{"id":1219,"level":95},"step-1-confirm-where-you-are",[16,1221,1222],{"id":1219},"Step 1: Confirm Where You Are",[37,1224,1225],{},"Run:",[1227,1228],"code-snippet",{"language":1229,"src":1230},"bash","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[37,1232,1233],{},"Expected result: a folder path",[37,1235,1236],{},"If you see a path, the terminal is working and you know your current location",[11,1238,1240,1243,1245,1248,1251,1254,1257],{"id":1239,"level":95},"step-2-list-files",[16,1241,1242],{"id":1239},"Step 2: List Files",[37,1244,1225],{},[1227,1246],{"language":1229,"src":1247},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[37,1249,1250],{},"Expected result: file and folder names from your current location",[37,1252,1253],{},"For hidden files and details too, run:",[1227,1255],{"language":1229,"src":1256},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[21,1258,1259,1264,1269],{},[24,1260,1261,1263],{},[262,1262,964],{}," includes hidden files",[24,1265,1266,1268],{},[262,1267,972],{}," uses a long listing",[24,1270,1271,1274],{},[262,1272,1273],{},"-la"," combines both",[11,1276,1278,1281,1284,1287,1294,1300],{"id":1277,"level":95},"step-3-change-folders",[16,1279,1280],{"id":1277},"Step 3: Change Folders",[37,1282,1283],{},"Start from your home folder, then move up and back",[1227,1285],{"language":1229,"src":1286},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[37,1288,1289,1290,1293],{},"This avoids assuming your computer has a specific folder like ",[262,1291,1292],{},"Documents"," in the current location",[37,1295,1296,1297,1299],{},"When you move into a named folder later, run ",[262,1298,1156],{}," first and pick a folder that actually appears in the list",[37,1301,1302],{},"If a path has spaces, wrap it in quotes",[11,1304,1306,1310,1312,1315],{"id":1305,"level":95},"step-4-create-practice-folder",[16,1307,1309],{"id":1308},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[37,1311,1225],{},[1227,1313],{"language":1229,"src":1314},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[37,1316,1317,1318,1320,1321],{},"Expected result: ",[262,1319,1035],{}," ends with ",[262,1322,1323],{},"cli-practice",[11,1325,1327,1331,1333,1336,1339],{"id":1326,"level":95},"step-5-create-and-read-file",[16,1328,1330],{"id":1329},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[37,1332,1225],{},[1227,1334],{"language":1229,"src":1335},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[37,1337,1338],{},"What this command does:",[21,1340,1341,1347,1353],{},[24,1342,1343,1346],{},[262,1344,1345],{},"echo"," prepares text for the terminal",[24,1348,1349,1352],{},[262,1350,1351],{},">"," redirects that text into a file instead of printing it on screen",[24,1354,1355,1358],{},[262,1356,1357],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,1360,1362,1366,1369,1372,1378],{"id":1361,"level":95},"step-5-read-file-back",[361,1363,1365],{"id":1364},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[37,1367,1368],{},"Then read it back:",[1227,1370],{"language":1229,"src":1371},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[37,1373,1374,1377],{},[262,1375,1376],{},"cat"," prints file contents in the terminal",[37,1379,1380],{},"Expected result: the terminal prints the text you wrote",[11,1382,1384,1388,1390,1399,1402,1428,1431],{"id":1383,"level":14},"file-management-loop",[16,1385,1387],{"id":1386},"practice-2-file-management","Practice 2: File Management",[37,1389,1200],{},[159,1391,1392,1394,1396],{},[24,1393,1205],{},[24,1395,1208],{},[24,1397,1398],{},"Confirm the file changed the way you expected",[37,1400,1401],{},"Commands in this practice:",[21,1403,1404,1410,1416,1422],{},[24,1405,1406,1409],{},[262,1407,1408],{},"touch"," creates an empty file",[24,1411,1412,1415],{},[262,1413,1414],{},"cp"," copies a file or folder",[24,1417,1418,1421],{},[262,1419,1420],{},"mv"," moves or renames",[24,1423,1424,1427],{},[262,1425,1426],{},"rm"," deletes",[37,1429,1430],{},"Important flags:",[21,1432,1433,1439,1445,1451],{},[24,1434,1435,1438],{},[262,1436,1437],{},"cp -r"," copies folders",[24,1440,1441,1444],{},[262,1442,1443],{},"rm -r"," deletes folders",[24,1446,1447,1450],{},[262,1448,1449],{},"rm -f"," forces deletion",[24,1452,1216],{},[11,1454,1456,1460,1462,1465,1470],{"id":1455,"level":95},"practice-2-step-1-create-empty-file",[16,1457,1459],{"id":1458},"step-1-create-an-empty-file","Step 1: Create An Empty File",[37,1461,1225],{},[1227,1463],{"language":1229,"src":1464},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[37,1466,1467,1469],{},[262,1468,1408],{}," creates an empty file, or updates the timestamp if the file already exists",[37,1471,1317,1472,1475],{},[262,1473,1474],{},"practice-empty.txt"," appears in the folder list",[11,1477,1479,1483,1485,1488,1491,1497,1510],{"id":1478,"level":95},"practice-2-step-2-copy-rename-and-delete",[16,1480,1482],{"id":1481},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[37,1484,1225],{},[1227,1486],{"language":1229,"src":1487},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[37,1489,1490],{},"Expected result: the backup is copied, renamed, then removed",[37,1492,1493,1494,1496],{},"Use ",[262,1495,1426],{}," carefully. Deleting from the terminal usually skips the recycle bin",[21,1498,1499,1504],{},[24,1500,1501,1503],{},[262,1502,968],{},": recursive, includes folders and everything inside them",[24,1505,1506,1509],{},[262,1507,1508],{},"-f",": force, skips many confirmation prompts",[1511,1512,1514],"alert",{"color":1513},"red",[37,1515,1516,1517,1520],{},"Never run ",[262,1518,1519],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,1522,1524,1528,1531,1549,1554,1559,1579],{"id":1523,"level":14},"terminal-editors",[16,1525,1527],{"id":1526},"practice-3-terminal-editors","Practice 3: Terminal Editors",[37,1529,1530],{},"Sometimes you need to edit a file from a terminal",[21,1532,1533,1539],{},[24,1534,1535,1538],{},[262,1536,1537],{},"nano"," is beginner-friendly",[24,1540,1541,1544,1545,1548],{},[262,1542,1543],{},"vi"," or ",[262,1546,1547],{},"vim"," is common on servers but has a learning curve",[37,1550,1493,1551,1553],{},[262,1552,1537],{}," for this course unless a lesson says otherwise",[37,1555,1493,1556,1558],{},[262,1557,1189],{}," when line numbers would help",[37,1560,1561,1562,1544,1564,1566,1567,1570,1571,1574,1575,1578],{},"If you accidentally open ",[262,1563,1543],{},[262,1565,1547],{},", press ",[262,1568,1569],{},"Esc",", type ",[262,1572,1573],{},":q",", and press ",[262,1576,1577],{},"Enter"," to exit without saving",[21,1580,1581],{},[24,1582,1583],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,1585,1587,1592,1594,1597,1602,1624],{"id":1586,"level":95},"edit-with-nano",[16,1588,1589,1590],{"id":1586},"Edit With ",[262,1591,1537],{},[37,1593,1225],{},[1227,1595],{"language":1229,"src":1596},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[37,1598,301,1599,1601],{},[262,1600,1537],{},":",[21,1603,1604,1607,1614,1618],{},[24,1605,1606],{},"Type a short note",[24,1608,1609,1610,1613],{},"Press ",[262,1611,1612],{},"Ctrl+O"," to save",[24,1615,1609,1616],{},[262,1617,1577],{},[24,1619,1609,1620,1623],{},[262,1621,1622],{},"Ctrl+X"," to exit",[37,1625,1626,1627,1629,1630,1570,1632,1574,1634],{},"If you open ",[262,1628,1543],{}," by mistake, press ",[262,1631,1569],{},[262,1633,1573],{},[262,1635,1577],{},[11,1637,1639,1645,1650,1653,1656,1659],{"id":1638,"level":14},"sudo-and-permission-boundaries",[16,1640,1641,1644],{"id":1638},[262,1642,1643],{},"sudo"," And Permission Boundaries",[37,1646,1647,1649],{},[262,1648,1643],{}," runs a command with elevated permissions",[37,1651,1652],{},"Use it only when a setup lesson explicitly says to use it",[37,1654,1655],{},"Example:",[1227,1657],{"language":1229,"src":1658},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[21,1660,1661],{},[24,1662,1663],{},"See the slide below for supporting examples and follow-up details",[11,1665,1667,1672,1678],{"id":1666,"level":95},"sudo-by-operating-system",[361,1668,1669,1671],{"id":1666},[262,1670,1643],{}," By Operating System",[37,1673,1674,1675,1677],{},"On Linux and macOS, ",[262,1676,1643],{}," is common for package installation and service management",[37,1679,1680,1681,1683],{},"Modern Windows also has a native ",[262,1682,1643],{}," 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,1685,1687,1690,1693,1704],{"id":1686,"level":14},"quick-safety-routine",[16,1688,1689],{"id":1686},"Quick Safety Routine",[37,1691,1692],{},"Before a command changes files, ask:",[21,1694,1695,1698,1701],{},[24,1696,1697],{},"What folder am I in?",[24,1699,1700],{},"Do I see the files I expect?",[24,1702,1703],{},"Am I about to change the right folder?",[37,1705,1706,1707,1709,1710],{},"If one answer is unclear, stop and run ",[262,1708,1035],{}," plus ",[262,1711,1712],{},"ls -la",[11,1714,1716,1719],{"id":1715,"level":14},"common-mistakes",[16,1717,1718],{"id":1715},"Common Mistakes",[21,1720,1721,1737,1743,1751],{},[24,1722,1723,1726,1727,1729,1730,1732,1733,1736],{},[262,1724,1725],{},"No such file or directory",": run ",[262,1728,1035],{},", then ",[262,1731,1156],{},", then try ",[262,1734,1735],{},"cd"," again",[24,1738,1739,1740,1742],{},"Command affected the wrong folder: check ",[262,1741,1035],{}," before continuing",[24,1744,1745,1747,1748,1750],{},[262,1746,1376],{}," cannot find the file: run ",[262,1749,1712],{}," and check the exact filename",[24,1752,1663],{},[11,1754,1756,1760],{"id":1755,"level":95},"common-mistakes-recovery",[361,1757,1759],{"id":1758},"recovery-checks","Recovery Checks",[21,1761,1762,1765,1771,1777],{},[24,1763,1764],{},"Spaces in a path: wrap the path in quotes",[24,1766,1767,1768],{},"Command keeps running: press ",[262,1769,1770],{},"Ctrl+C",[24,1772,1773,1774],{},"Permission denied: move back home with ",[262,1775,1776],{},"cd ~",[24,1778,1779,1780,1782],{},"Wrong ",[262,1781,1426],{},": stop and ask before doing more work",[11,1784,1785,1787,1790],{"id":433,"level":14},[16,1786,436],{"id":433},[37,1788,1789],{},"You are ready for the next setup lesson when these commands make sense:",[1227,1791],{"language":1229,"src":1792},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,1794,1796,1800],{"id":1795,"level":14},"further-learning",[16,1797,1799],{"id":1798},"key-terms-and-further-learning","Key Terms And Further Learning",[100,1801,1802,1834],{"gap":102,"left-width":103,"right-width":103},[105,1803,1804,1808,1814,1823],{"v-slot:left":107},[361,1805,1807],{"id":1806},"key-terms","Key Terms",[37,1809,1810,1813],{},[122,1811,1812],{},"Working directory"," - The folder where the next terminal command runs",[37,1815,1816,1819,1820],{},[122,1817,1818],{},"Path"," - A file or folder location, such as ",[262,1821,1822],{},"public_html\u002Findex.php",[37,1824,1825,1828,1829,1831,1832],{},[122,1826,1827],{},"Flag"," - An extra command option, such as ",[262,1830,1273],{}," in ",[262,1833,1712],{},[105,1835,1836,1839],{"v-slot:right":107},[361,1837,1838],{"id":1795},"Further Learning",[21,1840,1841,1848,1855],{},[24,1842,1843],{},[41,1844,1847],{"href":1845,"rel":1846},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[45],"Ubuntu Tutorial: The Linux Command Line For Beginners",[24,1849,1850],{},[41,1851,1854],{"href":1852,"rel":1853},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[45],"GNU Coreutils Manual",[24,1856,1857],{},[41,1858,1861],{"href":1859,"rel":1860},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[45],"MDN: Command Line Crash Course",[11,1863,1864,1866,1869],{"id":462,"level":14},[16,1865,465],{"id":462},[37,1867,1868],{},"Before leaving this presentation, confirm you can:",[21,1870,1871,1876,1881,1892,1906],{},[24,1872,1493,1873,1875],{},[262,1874,1035],{}," to check where commands will run",[24,1877,1493,1878,1880],{},[262,1879,1712],{}," to inspect the current folder",[24,1882,1493,1883,965,1885,965,1887,969,1889,1891],{},[262,1884,1735],{},[262,1886,1100],{},[262,1888,1106],{},[262,1890,1132],{}," to move intentionally",[24,1893,1894,1895,965,1897,965,1899,965,1901,969,1903,1905],{},"Use file commands such as ",[262,1896,1408],{},[262,1898,1414],{},[262,1900,1420],{},[262,1902,1426],{},[262,1904,1537],{}," carefully",[24,1907,1908],{},"Stop and check location when output does not match the lesson",{"title":107,"searchDepth":489,"depth":489,"links":1910},[1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1925,1926,1927,1928,1929,1931,1936,1937,1940,1941,1942],{"id":889,"depth":489,"text":890},{"id":944,"depth":489,"text":947},{"id":981,"depth":489,"text":984},{"id":1016,"depth":489,"text":1017},{"id":1075,"depth":489,"text":1078},{"id":1142,"depth":489,"text":1145},{"id":1196,"depth":489,"text":1197},{"id":1219,"depth":489,"text":1222},{"id":1239,"depth":489,"text":1242},{"id":1277,"depth":489,"text":1280},{"id":1308,"depth":489,"text":1309},{"id":1329,"depth":489,"text":1330,"children":1923},[1924],{"id":1364,"depth":501,"text":1365},{"id":1386,"depth":489,"text":1387},{"id":1458,"depth":489,"text":1459},{"id":1481,"depth":489,"text":1482},{"id":1526,"depth":489,"text":1527},{"id":1586,"depth":489,"text":1930},"Edit With nano",{"id":1638,"depth":489,"text":1932,"children":1933},"sudo And Permission Boundaries",[1934],{"id":1666,"depth":501,"text":1935},"sudo By Operating System",{"id":1686,"depth":489,"text":1689},{"id":1715,"depth":489,"text":1718,"children":1938},[1939],{"id":1758,"depth":501,"text":1759},{"id":433,"depth":489,"text":436},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"Practice the terminal commands you need so you can move through folders, inspect files, and verify your location before running course commands.","Face-to-face class of about 40 students; includes short CLI demo, student command practice, path\u002Fflag checks, and common beginner recovery questions.","45","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":881,"description":1943},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[1952,1953,1954],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":1960,"title":1961,"audience":6,"body":1962,"contentType":505,"course":506,"description":2836,"estimateBasis":2837,"estimatedDiscussionMinutes":509,"estimatedLiveMinutes":2838,"estimatedTotalMinutes":1945,"extension":512,"meta":2839,"module":514,"navigation":515,"order":510,"path":2840,"promptAssist":518,"seo":2841,"status":520,"stem":2842,"tags":2843,"videoDuration":2844,"videoId":2845,"videoLink":2846,"videoTitle":1961,"week":514,"__hash__":2847},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":1963,"toc":2806},[1964,1987,2016,2044,2082,2113,2145,2180,2209,2239,2276,2279,2309,2340,2369,2419,2437,2454,2474,2499,2530,2548,2589,2634,2717,2777],[11,1965,1966,1968],{"id":944,"level":14},[16,1967,947],{"id":944},[21,1969,1970,1973,1976],{},[24,1971,1972],{},"Install Git",[24,1974,1975],{},"Choose one terminal for your operating system",[24,1977,1978,1979,965,1982,969,1984,1986],{},"Confirm ",[262,1980,1981],{},"git --version",[262,1983,1035],{},[262,1985,1712],{}," work before GitHub setup",[11,1988,1990,1994],{"id":1989,"level":14},"terminal-choice-by-os",[16,1991,1993],{"id":1992},"terminal-choices","Terminal Choices",[21,1995,1996,1999,2002,2005,2007,2010,2013],{},[24,1997,1998],{},"Pick the terminal for your operating system",[24,2000,2001],{},"Use that same terminal for this lesson path",[24,2003,2004],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[24,2006,992],{},[24,2008,2009],{},"Apple macOS: Terminal, with iTerm2 optional",[24,2011,2012],{},"Linux: Terminal, with Tilix optional",[24,2014,2015],{},"These operating system notes are alternatives, not a sequence",[11,2017,2019,2023,2041],{"id":2018,"level":14},"step-1-install-git-on-windows",[16,2020,2022],{"id":2021},"windows-path-git-bash","Windows Path: Git Bash",[159,2024,2025,2032,2035,2038],{},[24,2026,2027,2028],{},"Go to ",[41,2029,2030],{"href":2030,"rel":2031},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[45],[24,2033,2034],{},"Download and run the Git for Windows installer",[24,2036,2037],{},"Open Git Bash from the Start menu",[24,2039,2040],{},"Use Git Bash whenever this course says to use the terminal",[37,2042,2043],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,2045,2047,2050],{"id":2046,"level":95},"windows-installer-components",[361,2048,2049],{"id":2046},"Windows Installer: Components",[100,2051,2055,2063],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},"1.4fr","0.9fr","never",[105,2056,2057],{"v-slot:left":107},[37,2058,2059],{},[140,2060],{"alt":2061,"src":2062,"variant":144},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[105,2064,2065],{"v-slot:right":107},[21,2066,2067,2070,2076],{},[24,2068,2069],{},"Recommended to have these components selected",[24,2071,2072,2073],{},"Keep ",[262,2074,2075],{},"Git Bash Here",[24,2077,2078,2079],{},"Continue with ",[262,2080,2081],{},"Next",[11,2083,2085,2088],{"id":2084,"level":95},"windows-installer-default-editor",[361,2086,2087],{"id":2084},"Windows Installer: Default Editor",[100,2089,2090,2098],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2091,2092],{"v-slot:left":107},[37,2093,2094],{},[140,2095],{"alt":2096,"src":2097,"variant":144},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[105,2099,2100],{"v-slot:right":107},[21,2101,2102,2105,2110],{},[24,2103,2104],{},"Choose the editor you are comfortable with",[24,2106,2107,2109],{},[262,2108,1537],{}," or VS Code is friendlier than Vim for most beginners",[24,2111,2112],{},"This setting affects Git messages if Git opens an editor",[11,2114,2116,2119],{"id":2115,"level":95},"windows-installer-branch-name",[361,2117,2118],{"id":2115},"Windows Installer: Branch Name",[100,2120,2121,2129],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2122,2123],{"v-slot:left":107},[37,2124,2125],{},[140,2126],{"alt":2127,"src":2128,"variant":144},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[105,2130,2131],{"v-slot:right":107},[21,2132,2133,2139,2142],{},[24,2134,2135,2136],{},"Select the option that uses ",[262,2137,2138],{},"main",[24,2140,2141],{},"Course repositories will tell you which branch to use later",[24,2143,2144],{},"Do not create custom branch names here",[11,2146,2148,2151],{"id":2147,"level":95},"windows-installer-path",[361,2149,2150],{"id":2147},"Windows Installer: PATH",[100,2152,2153,2161],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2154,2155],{"v-slot:left":107},[37,2156,2157],{},[140,2158],{"alt":2159,"src":2160,"variant":144},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[105,2162,2163],{"v-slot:right":107},[21,2164,2165,2168,2174,2177],{},[24,2166,2167],{},"Select the recommended PATH option",[24,2169,2170,2171],{},"This lets Git Bash and common tools find ",[262,2172,2173],{},"git",[24,2175,2176],{},"Avoid options that say Git Bash only",[24,2178,2179],{},"The third option can be used if you understand the consequences",[11,2181,2183,2186],{"id":2182,"level":95},"windows-installer-ssh",[361,2184,2185],{"id":2182},"Windows Installer: SSH",[100,2187,2188,2196],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2189,2190],{"v-slot:left":107},[37,2191,2192],{},[140,2193],{"alt":2194,"src":2195,"variant":144},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[105,2197,2198],{"v-slot:right":107},[21,2199,2200,2203,2206],{},[24,2201,2202],{},"Use the bundled OpenSSH option",[24,2204,2205],{},"This keeps Git Bash SSH behavior predictable",[24,2207,2208],{},"SSH setup happens in the next lesson",[11,2210,2212,2216],{"id":2211,"level":95},"windows-installer-openssl",[361,2213,2215],{"id":2214},"windows-installer-https","Windows Installer: HTTPS",[100,2217,2218,2226],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2219,2220],{"v-slot:left":107},[37,2221,2222],{},[140,2223],{"alt":2224,"src":2225,"variant":144},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[105,2227,2228],{"v-slot:right":107},[21,2229,2230,2233,2236],{},[24,2231,2232],{},"Keep the OpenSSL option",[24,2234,2235],{},"This is the normal Git for Windows choice",[24,2237,2238],{},"It supports secure GitHub connections",[11,2240,2242,2246],{"id":2241,"level":95},"windows-installer-checkout-style",[361,2243,2245],{"id":2244},"windows-installer-line-endings","Windows Installer: Line Endings",[100,2247,2248,2256],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2249,2250],{"v-slot:left":107},[37,2251,2252],{},[140,2253],{"alt":2254,"src":2255,"variant":144},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[105,2257,2258,2269],{"v-slot:right":107},[21,2259,2260,2263,2266],{},[24,2261,2262],{},"Keep the default line-ending option",[24,2264,2265],{},"Git handles Windows and Linux line endings for you",[24,2267,2268],{},"Do not change this unless a lesson says to",[2270,2271,2273],"admonition",{"type":2272},"note",[37,2274,2275],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[37,2277,2278],{},"::\n::",[11,2280,2282,2286],{"id":2281,"level":95},"windows-installer-mintty",[361,2283,2285],{"id":2284},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[100,2287,2288,2296],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2289,2290],{"v-slot:left":107},[37,2291,2292],{},[140,2293],{"alt":2294,"src":2295,"variant":144},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[105,2297,2298],{"v-slot:right":107},[21,2299,2300,2303,2306],{},[24,2301,2302],{},"Keep MinTTY selected",[24,2304,2305],{},"This is the normal Git Bash window",[24,2307,2308],{},"Course screenshots will assume this terminal style",[11,2310,2312,2316],{"id":2311,"level":95},"windows-installer-fast-forward",[361,2313,2315],{"id":2314},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[100,2317,2318,2326],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2319,2320],{"v-slot:left":107},[37,2321,2322],{},[140,2323],{"alt":2324,"src":2325,"variant":144},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[105,2327,2328],{"v-slot:right":107},[21,2329,2330,2337],{},[24,2331,2332,2333,2336],{},"Keep the default ",[262,2334,2335],{},"git pull"," behavior",[24,2338,2339],{},"Later lessons explain pull, merge, and conflicts",[11,2341,2343,2346],{"id":2342,"level":95},"windows-installer-credential-manager",[361,2344,2345],{"id":2342},"Windows Installer: Credential Manager",[100,2347,2348,2356],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2349,2350],{"v-slot:left":107},[37,2351,2352],{},[140,2353],{"alt":2354,"src":2355,"variant":144},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[105,2357,2358],{"v-slot:right":107},[21,2359,2360,2363,2366],{},[24,2361,2362],{},"Keep Git Credential Manager enabled",[24,2364,2365],{},"It helps with browser-based GitHub sign-in",[24,2367,2368],{},"This course still uses SSH for repo pushes",[11,2370,2372,2375],{"id":2371,"level":95},"windows-installer-extra-options",[361,2373,2374],{"id":2371},"Windows Installer: Extra Options",[100,2376,2377,2385],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,2378,2379],{"v-slot:left":107},[37,2380,2381],{},[140,2382],{"alt":2383,"src":2384,"variant":144},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[105,2386,2387],{"v-slot:right":107},[21,2388,2389,2397,2408,2416],{},[24,2390,2391,2392],{},"Enable file system caching\n",[21,2393,2394],{},[24,2395,2396],{},"Improves Git performance on Windows",[24,2398,2399,2400],{},"Enable symbolic links if available\n",[21,2401,2402,2405],{},[24,2403,2404],{},"Helps Git handle link-like files correctly",[24,2406,2407],{},"May require Windows Developer Mode or admin rights",[24,2409,2410,2411],{},"Skip experimental options\n",[21,2412,2413],{},[24,2414,2415],{},"They can change behavior between Git versions",[24,2417,2418],{},"Finish the installer",[11,2420,2422,2426],{"id":2421,"level":95},"step-1-open-git-bash-on-windows",[361,2423,2425],{"id":2424},"open-git-bash","Open Git Bash",[21,2427,2428,2431,2434],{},[24,2429,2430],{},"Start menu -> Git Bash",[24,2432,2433],{},"Pin it if that helps you find the same terminal later",[24,2435,2436],{},"Run the checks in the next slides from Git Bash",[11,2438,2440,2443],{"id":2439,"level":95},"windows-terminal-habit",[361,2441,2442],{"id":2439},"Windows Terminal Habit",[21,2444,2445,2448,2451],{},[24,2446,2447],{},"Use Git Bash for course commands on Windows",[24,2449,2450],{},"If another terminal opens by accident, close it and open Git Bash",[24,2452,2453],{},"Staying in one terminal makes setup problems easier to diagnose",[11,2455,2457,2460],{"id":2456,"level":14},"macos-path-terminal",[16,2458,2459],{"id":2456},"macOS Path: Terminal",[21,2461,2462,2465,2468,2471],{},[24,2463,2464],{},"Built-in Terminal is fully supported",[24,2466,2467],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[24,2469,2470],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[24,2472,2473],{},"See the slide below for the optional modern terminal install path",[11,2475,2477,2481],{"id":2476,"level":95},"macos-optional-iterm2-install",[361,2478,2480],{"id":2479},"optional-iterm2-install","Optional iTerm2 Install",[21,2482,2483,2490,2493,2496],{},[24,2484,2485,2486],{},"Download the stable release from ",[41,2487,2488],{"href":2488,"rel":2489},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[45],[24,2491,2492],{},"Move iTerm2 to Applications",[24,2494,2495],{},"Open iTerm2 and run the same checks as Terminal",[24,2497,2498],{},"Use Terminal or iTerm2 consistently for course commands",[11,2500,2502,2505,2519,2522,2525],{"id":2501,"level":14},"linux-path-terminal",[16,2503,2504],{"id":2501},"Linux Path: Terminal",[21,2506,2507,2510,2513],{},[24,2508,2509],{},"Open the built-in Terminal app",[24,2511,2512],{},"Git is often installed already",[24,2514,2515,2516,2518],{},"If ",[262,2517,1981],{}," fails, use your distribution package manager",[37,2520,2521],{},"For Ubuntu:",[1227,2523],{"language":1229,"src":2524},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[21,2526,2527],{},[24,2528,2529],{},"See the slide below for the optional split-pane terminal setup",[11,2531,2533,2537,2540,2542,2545],{"id":2532,"level":95},"linux-optional-tilix-install",[361,2534,2536],{"id":2535},"optional-tilix-install","Optional Tilix Install",[37,2538,2539],{},"Tilix is a Linux terminal with split panes and profiles",[37,2541,2521],{},[1227,2543],{"language":1229,"src":2544},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[37,2546,2547],{},"Use the built-in Terminal if optional installs add friction",[11,2549,2551,2555],{"id":2550,"level":14},"step-3-confirm-git-and-shell",[16,2552,2554],{"id":2553},"confirm-git-and-shell","Confirm Git And Shell",[100,2556,2559,2573],{"gap":102,"left-width":2557,"right-width":2558},"1.15fr","0.85fr",[105,2560,2561,2563,2566,2569],{"v-slot:left":107},[37,2562,1225],{},[1227,2564],{"language":1229,"src":2565},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[37,2567,2568],{},"Expected output:",[1227,2570],{"language":2571,"src":2572},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[105,2574,2575,2578],{"v-slot:right":107},[37,2576,2577],{},"This confirms:",[21,2579,2580,2583,2586],{},[24,2581,2582],{},"Git is installed",[24,2584,2585],{},"The terminal can find Git",[24,2587,2588],{},"Your shell matches later course commands",[11,2590,2592,2596],{"id":2591,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,2593,2595],{"id":2594},"check-location-before-git-commands","Check Location Before Git Commands",[100,2597,2599,2611],{"gap":102,"left-width":2598,"right-width":2053},"1.1fr",[105,2600,2601,2603,2606,2608],{"v-slot:left":107},[37,2602,1225],{},[1227,2604],{"language":1229,"src":2605},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[37,2607,2568],{},[1227,2609],{"language":2571,"src":2610},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[105,2612,2613,2616],{"v-slot:right":107},[37,2614,2615],{},"Use this before Git commands:",[21,2617,2618,2623,2628,2631],{},[24,2619,2620,2622],{},[262,2621,1035],{}," shows the current folder",[24,2624,2625,2627],{},[262,2626,1712],{}," shows what is inside it",[24,2629,2630],{},"If the folder is wrong, fix location first",[24,2632,2633],{},"Do not run Git commands while guessing",[11,2635,2636,2638],{"id":1715,"level":14},[16,2637,1718],{"id":1715},[100,2639,2640,2683],{"gap":102,"left-width":103,"right-width":103},[105,2641,2642],{"v-slot:left":107},[21,2643,2644,2657,2675],{},[24,2645,2646,2649],{},[262,2647,2648],{},"git: command not found",[21,2650,2651,2654],{},[24,2652,2653],{},"Git is missing, or this terminal cannot find it",[24,2655,2656],{},"Close the terminal and reopen the correct one",[24,2658,2659,2662],{},[262,2660,2661],{},"not a git repository",[21,2663,2664,2667],{},[24,2665,2666],{},"The command ran outside a cloned repository",[24,2668,1493,2669,2671,2672,2674],{},[262,2670,1035],{}," and ",[262,2673,1712],{},", then move to the repo folder",[24,2676,2677,2678],{},"Wrong terminal",[21,2679,2680],{},[24,2681,2682],{},"Windows users should switch back to Git Bash",[105,2684,2685,2688],{"v-slot:right":107},[24,2686,2687],{},"Too many terminals open",[159,2689,2690,2693,2703,2708,2714],{},[24,2691,2692],{},"Close extra terminal windows",[24,2694,2695,2696],{},"Open the correct terminal\n",[21,2697,2698,2700],{},[24,2699,992],{},[24,2701,2702],{},"Apple macOS\u002FLinux: Terminal",[24,2704,2705,2706],{},"Run ",[262,2707,1981],{},[24,2709,2705,2710,2671,2712],{},[262,2711,1035],{},[262,2713,1712],{},[24,2715,2716],{},"Continue only after the folder looks right",[11,2718,2719,2721],{"id":1795,"level":14},[16,2720,1799],{"id":1798},[100,2722,2723,2745],{"gap":102,"left-width":103,"right-width":103},[105,2724,2725,2727,2733,2739],{"v-slot:left":107},[361,2726,1807],{"id":1806},[37,2728,2729,2732],{},[122,2730,2731],{},"Terminal"," - A text-based interface where you type commands to control your computer",[37,2734,2735,2738],{},[122,2736,2737],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[37,2740,2741,2744],{},[122,2742,2743],{},"Git"," - A tool for tracking changes in code files over time",[105,2746,2747,2749],{"v-slot:right":107},[361,2748,1838],{"id":1795},[21,2750,2751,2758,2764,2770],{},[24,2752,2753],{},[41,2754,2757],{"href":2755,"rel":2756},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[45],"Git Downloads",[24,2759,2760],{},[41,2761,2763],{"href":2030,"rel":2762},[45],"Git For Windows Install Page",[24,2765,2766],{},[41,2767,2769],{"href":2488,"rel":2768},[45],"iTerm2 Downloads",[24,2771,2772],{},[41,2773,2776],{"href":2774,"rel":2775},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[45],"Tilix",[11,2778,2779,2781,2784],{"id":462,"level":14},[16,2780,465],{"id":462},[37,2782,2783],{},"Before moving on, confirm you can:",[21,2785,2786,2789,2793,2800,2803],{},[24,2787,2788],{},"Open the correct terminal for your operating system",[24,2790,2705,2791],{},[262,2792,1981],{},[24,2794,1493,2795,2671,2797,2799],{},[262,2796,1035],{},[262,2798,1712],{}," to check your location",[24,2801,2802],{},"Understand what terminal\u002FCLI refers to",[24,2804,2805],{},"Keep track of terminal instances",{"title":107,"searchDepth":489,"depth":489,"links":2807},[2808,2809,2810,2825,2828,2831,2832,2833,2834,2835],{"id":944,"depth":489,"text":947},{"id":1992,"depth":489,"text":1993},{"id":2021,"depth":489,"text":2022,"children":2811},[2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824],{"id":2046,"depth":501,"text":2049},{"id":2084,"depth":501,"text":2087},{"id":2115,"depth":501,"text":2118},{"id":2147,"depth":501,"text":2150},{"id":2182,"depth":501,"text":2185},{"id":2214,"depth":501,"text":2215},{"id":2244,"depth":501,"text":2245},{"id":2284,"depth":501,"text":2285},{"id":2314,"depth":501,"text":2315},{"id":2342,"depth":501,"text":2345},{"id":2371,"depth":501,"text":2374},{"id":2424,"depth":501,"text":2425},{"id":2439,"depth":501,"text":2442},{"id":2456,"depth":489,"text":2459,"children":2826},[2827],{"id":2479,"depth":501,"text":2480},{"id":2501,"depth":489,"text":2504,"children":2829},[2830],{"id":2535,"depth":501,"text":2536},{"id":2553,"depth":489,"text":2554},{"id":2594,"depth":489,"text":2595},{"id":1715,"depth":489,"text":1718},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"Install Git and choose the correct terminal for course commands.","Face-to-face class of about 40 students; includes OS-specific terminal choices, Git installation, short checks, and setup friction.","35",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",{"title":1961,"description":2836},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[2173,1953,526],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":2849,"title":2850,"audience":6,"body":2851,"contentType":505,"course":506,"description":3926,"estimateBasis":3927,"estimatedDiscussionMinutes":3928,"estimatedLiveMinutes":3929,"estimatedTotalMinutes":3930,"extension":512,"meta":3931,"module":514,"navigation":515,"order":511,"path":3932,"promptAssist":518,"seo":3933,"status":520,"stem":3934,"tags":3935,"videoDuration":3939,"videoId":3940,"videoLink":3941,"videoTitle":3942,"week":514,"__hash__":3943},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":2852,"toc":3898},[2853,2879,2897,2922,2935,2962,2999,3076,3124,3191,3267,3309,3335,3367,3405,3450,3484,3553,3555,3558,3569,3641,3670,3704,3752,3798,3866],[11,2854,2856,2859],{"id":2855,"level":14},"goals",[16,2857,2858],{"id":2855},"Goals",[21,2860,2861,2864,2867,2870,2873,2876],{},[24,2862,2863],{},"Confirm Git works in the correct terminal",[24,2865,2866],{},"Sign in to GitHub with a school or personal account",[24,2868,2869],{},"Create or reuse an SSH key for GitHub",[24,2871,2872],{},"Add the public key to GitHub",[24,2874,2875],{},"Create and clone your course repository",[24,2877,2878],{},"Set Git identity inside the cloned repository",[11,2880,2882,2885,2894],{"id":2881,"level":14},"terminal-by-os",[16,2883,2884],{"id":2881},"Terminal By OS",[21,2886,2887,2889,2892],{},[24,2888,992],{},[24,2890,2891],{},"Apple macOS: Terminal or iTerm2",[24,2893,1007],{},[37,2895,2896],{},"Run these commands on your own computer",[11,2898,2900,2903],{"id":2899,"level":14},"git-and-ssh-terms",[16,2901,2902],{"id":2899},"Git And SSH Terms",[21,2904,2905,2908,2916,2919],{},[24,2906,2907],{},"Git identity: name and email attached to commits in a repository",[24,2909,2910,2911],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[21,2912,2913],{},[24,2914,2915],{},"This is how we'll authenticate to GitHub",[24,2917,2918],{},"SSH agent: helper that keeps your private key available to Git commands",[24,2920,2921],{},"Clone: local folder connected to a GitHub repository",[11,2923,2925,2928,2932],{"id":2924,"level":14},"ssh-key-flow",[16,2926,2927],{"id":2924},"SSH Key Flow",[2929,2930],"mermaid",{"code":2931},"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",[37,2933,2934],{},"GitHub receives only the public key. The private key stays on your computer",[11,2936,2938,2941],{"id":2937,"level":14},"step-1-check-git",[16,2939,2940],{"id":2937},"Step 1: Check Git",[100,2942,2943,2951],{"gap":102,"left-width":103,"right-width":103},[105,2944,2945,2947],{"v-slot:left":107},[37,2946,1225],{},[1227,2948],{"label":2949,"language":1229,"src":2950},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[105,2952,2953,2955,2959],{"v-slot:right":107},[37,2954,2568],{},[1227,2956],{"label":2957,"language":2571,"src":2958},"example-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[37,2960,2961],{},"A valid version means Git is installed and available in this terminal",[11,2963,2965,2969],{"id":2964,"level":14},"step-2-github-account",[16,2966,2968],{"id":2967},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[100,2970,2972,2991],{"gap":102,"left-width":103,"right-width":2971},"0.8fr",[105,2973,2974],{"v-slot:left":107},[21,2975,2976,2979,2982,2985,2988],{},[24,2977,2978],{},"Use an existing GitHub account or create one",[24,2980,2981],{},"School email recommended for course identity",[24,2983,2984],{},"Personal email is fine if you prefer it",[24,2986,2987],{},"Avoid work email so course access does not depend on an employer account",[24,2989,2990],{},"Confirm you can open GitHub Settings before continuing",[105,2992,2993],{"v-slot:right":107},[37,2994,2995],{},[140,2996],{"alt":2997,"src":2998,"variant":144},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3000,3002,3006],{"id":3001,"level":14},"step-2-create-repo",[16,3003,3005],{"id":3004},"step-3-create-course-repository","Step 3: Create Course Repository",[100,3007,3009,3068],{"gap":102,"left-width":3008,"right-width":2557},"0.95fr",[105,3010,3011,3014],{"v-slot:left":107},[37,3012,3013],{},"In GitHub:",[21,3015,3016,3021,3027,3033,3048,3054,3057,3065],{},[24,3017,166,3018],{},[262,3019,3020],{},"+",[24,3022,3023,3024],{},"Choose ",[262,3025,3026],{},"New repository",[24,3028,3029,3030],{},"Name it ",[262,3031,3032],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[24,3034,3035,3036,3039,3040,3043,3044,3047],{},"Semester code examples: ",[262,3037,3038],{},"S2026"," spring, ",[262,3041,3042],{},"M2026"," summer, ",[262,3045,3046],{},"F2026"," fall",[24,3049,3050,3051],{},"Set visibility to ",[262,3052,3053],{},"Private",[24,3055,3056],{},"Toggle \"Add README\"",[24,3058,3059,3060],{},"Do not toggle \"Add .gitignore\"",[21,3061,3062],{},[24,3063,3064],{},"A future lesson will discuss and add this important file",[24,3066,3067],{},"Do not add starter files unless instructed",[105,3069,3070],{"v-slot:right":107},[37,3071,3072],{},[140,3073],{"alt":3074,"src":3075,"variant":144},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3077,3079,3083,3110],{"id":3078,"level":14},"step-3-check-existing-key",[16,3080,3082],{"id":3081},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[100,3084,3085,3093],{"gap":102,"left-width":103,"right-width":103},[105,3086,3087,3089],{"v-slot:left":107},[37,3088,1225],{},[1227,3090],{"label":3091,"language":1229,"src":3092},"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",[105,3094,3095,3098,3101],{"v-slot:right":107},[37,3096,3097],{},"Example output:",[1227,3099],{"label":2957,"language":2571,"src":3100},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[37,3102,3103,3104,2671,3107],{},"Look for a matching GitHub-specific pair such as ",[262,3105,3106],{},"github_key",[262,3108,3109],{},"github_key.pub",[37,3111,3112,3113,3116,3117,1544,3120,3123],{},"You can reuse an existing matching pair only if it is ",[122,3114,3115],{},"NOT"," a default key such as ",[262,3118,3119],{},"id_ed25519",[262,3121,3122],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3125,3127,3131,3133,3137,3139,3142],{"id":3126,"level":14},"step-4-create-key-if-needed",[16,3128,3130],{"id":3129},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[37,3132,1225],{},[1227,3134],{"label":3135,"language":1229,"src":3136},"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",[37,3138,3097],{},[1227,3140],{"label":2957,"language":2571,"src":3141},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[21,3143,3144,3170,3175,3180],{},[24,3145,3146,3147],{},"Command flags:\n",[21,3148,3149,3155,3161],{},[24,3150,3151,3154],{},[262,3152,3153],{},"-t"," chooses the key type",[24,3156,3157,3160],{},[262,3158,3159],{},"-C"," adds a comment label, usually your GitHub email",[24,3162,3163,3165,3166,3169],{},[262,3164,1508],{}," chooses the output file path (must include ",[262,3167,3168],{},"~\u002F.ssh\u002F"," followed by the file name)",[24,3171,3172,3174],{},[262,3173,3106],{}," is the private key file",[24,3176,3177,3179],{},[262,3178,3109],{}," is the public key file for GitHub",[24,3181,3182,3183],{},"Passphrase is optional unless your instructor requires one\n",[21,3184,3185,3188],{},[24,3186,3187],{},"Pro: protects the key if someone gets the file",[24,3189,3190],{},"Con: adds an unlock prompt when the key is used",[11,3192,3194,3198,3215,3247],{"id":3193,"level":14},"step-5-start-agent-and-add-key",[16,3195,3197],{"id":3196},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[100,3199,3200,3208],{"gap":102,"left-width":2598,"right-width":103},[105,3201,3202,3204],{"v-slot:left":107},[37,3203,1225],{},[1227,3205],{"label":3206,"language":1229,"src":3207},"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",[105,3209,3210,3212],{"v-slot:right":107},[37,3211,3097],{},[1227,3213],{"label":2957,"language":2571,"src":3214},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[21,3216,3217,3223,3244],{},[24,3218,3219,3222],{},[262,3220,3221],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[24,3224,3225,3226,3229,3230,3233],{},"If that fails, run ",[262,3227,3228],{},"exec ssh-agent bash",", then run ",[262,3231,3232],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[21,3234,3235],{},[24,3236,1493,3237,3240,3241,3243],{},[262,3238,3239],{},"~\u002F.ssh\u002Fgithub_key"," because ",[262,3242,1132],{}," avoids issues with spaces in home directory paths",[24,3245,3246],{},"Then verify the key is loaded",[100,3248,3249,3257],{"gap":102,"left-width":103,"right-width":103},[105,3250,3251,3253],{"v-slot:left":107},[37,3252,1225],{},[1227,3254],{"label":3255,"language":1229,"src":3256},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[105,3258,3259,3261,3264],{"v-slot:right":107},[37,3260,2568],{},[1227,3262],{"label":2957,"language":2571,"src":3263},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[37,3265,3266],{},"One loaded key is enough for this lesson",[11,3268,3270,3274,3291],{"id":3269,"level":14},"step-6-copy-public-key",[16,3271,3273],{"id":3272},"step-7-copy-public-key","Step 7: Copy Public Key",[100,3275,3276,3284],{"gap":102,"left-width":103,"right-width":103},[105,3277,3278,3280],{"v-slot:left":107},[37,3279,1225],{},[1227,3281],{"label":3282,"language":1229,"src":3283},"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",[105,3285,3286,3288],{"v-slot:right":107},[37,3287,3097],{},[1227,3289],{"label":2957,"language":2571,"src":3290},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[21,3292,3293,3303],{},[24,3294,3295,3296,3299,3300,3302],{},"Copy the full line starting with ",[262,3297,3298],{},"ssh-ed25519"," and ending with the value you set with ",[262,3301,3159],{}," earlier",[24,3304,3305,3306,3308],{},"Do not copy ",[262,3307,3106],{},", which is the private key (never share the private key)",[11,3310,3312,3316],{"id":3311,"level":14},"step-7-add-key-to-github",[16,3313,3315],{"id":3314},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[21,3317,3318,3321,3326,3329,3332],{},[24,3319,3320],{},"In GitHub, open account settings",[24,3322,2027,3323],{},[262,3324,3325],{},"SSH and GPG keys",[24,3327,3328],{},"Add a new authentication key",[24,3330,3331],{},"Paste the public key from the previous step",[24,3333,3334],{},"See the slides below for the GitHub screens",[11,3336,3338,3342],{"id":3337,"level":95},"step-8-open-github-settings",[361,3339,3341],{"id":3340},"open-github-settings","Open GitHub Settings",[100,3343,3344,3352],{"gap":102,"left-width":2598,"right-width":2053,"stack":2054},[105,3345,3346],{"v-slot:left":107},[37,3347,3348],{},[140,3349],{"alt":3350,"src":3351,"variant":144},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[105,3353,3354],{"v-slot:right":107},[21,3355,3356,3359,3364],{},[24,3357,3358],{},"Click your GitHub profile photo",[24,3360,3023,3361],{},[262,3362,3363],{},"Settings",[24,3365,3366],{},"Use the account menu, not the repository settings",[11,3368,3370,3374],{"id":3369,"level":95},"step-8-open-ssh-keys-page",[361,3371,3373],{"id":3372},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[100,3375,3376,3384],{"gap":102,"left-width":2598,"right-width":2053,"stack":2054},[105,3377,3378],{"v-slot:left":107},[37,3379,3380],{},[140,3381],{"alt":3382,"src":3383,"variant":144},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[105,3385,3386],{"v-slot:right":107},[21,3387,3388,3395,3400],{},[24,3389,3390,3391,3394],{},"Find the ",[262,3392,3393],{},"Access"," section",[24,3396,3397,3398],{},"Open ",[262,3399,3325],{},[24,3401,3023,3402],{},[262,3403,3404],{},"New SSH key",[11,3406,3408,3412],{"id":3407,"level":95},"step-8-add-new-ssh-key",[361,3409,3411],{"id":3410},"add-new-ssh-key","Add New SSH Key",[100,3413,3415,3423],{"gap":102,"left-width":3414,"right-width":2558,"stack":2054},"1.35fr",[105,3416,3417],{"v-slot:left":107},[37,3418,3419],{},[140,3420],{"alt":3421,"src":3422,"variant":144},"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",[105,3424,3425],{"v-slot:right":107},[21,3426,3427,3433,3439,3442,3447],{},[24,3428,3429,3430],{},"Title it clearly, such as ",[262,3431,3432],{},"\u003Ccourse> Laptop",[24,3434,3435,3436],{},"Keep key type as ",[262,3437,3438],{},"Authentication Key",[24,3440,3441],{},"Paste the full public key line",[24,3443,166,3444],{},[262,3445,3446],{},"Add SSH key",[24,3448,3449],{},"Never paste the private key",[11,3451,3453,3457],{"id":3452,"level":14},"step-8-test-auth",[16,3454,3456],{"id":3455},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[100,3458,3459,3474],{"gap":102,"left-width":103,"right-width":2598},[105,3460,3461,3463,3467],{"v-slot:left":107},[37,3462,1225],{},[1227,3464],{"label":3465,"language":1229,"src":3466},"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",[37,3468,3469,3470,3473],{},"If prompted the first time, type ",[262,3471,3472],{},"yes"," to trust GitHub's host key",[105,3475,3476,3478,3481],{"v-slot:right":107},[37,3477,2568],{},[1227,3479],{"label":2957,"language":2571,"src":3480},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[37,3482,3483],{},"This confirms authentication, then GitHub closes the connection",[11,3485,3487,3491],{"id":3486,"level":14},"step-9-clone-repo",[16,3488,3490],{"id":3489},"step-10-clone-course-repository","Step 10: Clone Course Repository",[100,3492,3493,3534],{"gap":102,"left-width":2053,"right-width":2598},[105,3494,3495,3499,3528],{"v-slot:left":107},[361,3496,3498],{"id":3497},"get-the-ssh-clone-url","Get The SSH Clone URL",[21,3500,3501,3507,3514,3521],{},[24,3502,3503,3504],{},"In your GitHub repository, click ",[262,3505,3506],{},"Code",[24,3508,3509,3510,3513],{},"Choose the ",[262,3511,3512],{},"SSH"," tab",[24,3515,3516,3517,3520],{},"Copy the ",[262,3518,3519],{},"git@github.com:..."," link",[24,3522,3523,3524,3527],{},"Use that link in the ",[262,3525,3526],{},"git clone"," command",[37,3529,3530],{},[140,3531],{"alt":3532,"src":3533,"variant":144},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[105,3535,3536,3539,3543],{"v-slot:right":107},[37,3537,3538],{},"Run from the folder that should contain your course repo:",[1227,3540],{"label":3541,"language":1229,"src":3542},"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",[2270,3544,3546],{"type":3545},"tip",[37,3547,3548,3549,3552],{},"Before cloning, run ",[262,3550,3551],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[37,3554,3097],{},[1227,3556],{"label":2957,"language":2571,"src":3557},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[37,3559,3560,3561,3564,3565,3568],{},"If you see an empty repository warning, you probably forgot to add ",[262,3562,3563],{},"README.md"," when creating the repo. Create it with ",[262,3566,3567],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,3570,3572,3576,3595,3614,3634],{"id":3571,"level":14},"step-10-set-repo-identity",[16,3573,3575],{"id":3574},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[100,3577,3578,3587],{"gap":102,"left-width":103,"right-width":103},[105,3579,3580,3583],{"v-slot:left":107},[37,3581,3582],{},"Run inside the cloned repository:",[1227,3584],{"label":3585,"language":1229,"src":3586},"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",[105,3588,3589,3591],{"v-slot:right":107},[37,3590,2568],{},[1227,3592],{"label":3593,"language":2571,"src":3594},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[100,3596,3597,3606],{"gap":102,"left-width":103,"right-width":103},[105,3598,3599,3602],{"v-slot:left":107},[37,3600,3601],{},"Then verify:",[1227,3603],{"label":3604,"language":1229,"src":3605},"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",[105,3607,3608,3610],{"v-slot:right":107},[37,3609,2568],{},[1227,3611],{"label":3612,"language":2571,"src":3613},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[21,3615,3616,3622,3628],{},[24,3617,3618,3621],{},[262,3619,3620],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[24,3623,3624,3627],{},[262,3625,3626],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[24,3629,3630,3633],{},[262,3631,3632],{},"core.sshCommand"," tells this repository to use your course GitHub key",[37,3635,3636,3637,3640],{},"These commands set identity for this repository. The ",[262,3638,3639],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,3642,3644,3648,3651,3667],{"id":3643,"level":14},"step-11-invite-collaborators",[16,3645,3647],{"id":3646},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[37,3649,3650],{},"In GitHub, open your course repository:",[21,3652,3653,3656,3661,3664],{},[24,3654,3655],{},"Settings -> Collaborators and teams",[24,3657,3658,3659],{},"Invite ",[262,3660,375],{},[24,3662,3663],{},"Invite your TA if your section has one",[24,3665,3666],{},"Wait until the invitation shows as sent or accepted",[37,3668,3669],{},"This is so it can be accessed for grading and assistance",[11,3671,3673,3676],{"id":3672,"level":14},"troubleshooting-auth",[16,3674,3675],{"id":3672},"Troubleshooting Auth",[21,3677,3678,3684,3691,3698,3701],{},[24,3679,3680,3683],{},[262,3681,3682],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[24,3685,3686,3687,3690],{},"No loaded key in ",[262,3688,3689],{},"ssh-add -l",": start the agent and add the key again",[24,3692,3693,3694,3697],{},"Wrong key in GitHub: delete it and paste the ",[262,3695,3696],{},".pub"," key again",[24,3699,3700],{},"Wrong account: make sure the success message names your GitHub account",[24,3702,3703],{},"See the slide below for a quick reset sequence",[11,3705,3707,3711,3713,3740],{"id":3706,"level":95},"troubleshooting-auth-recovery",[361,3708,3710],{"id":3709},"quick-reset-sequence","Quick Reset Sequence",[37,3712,1225],{},[159,3714,3715,3719,3723,3727,3732,3735],{},[24,3716,3717],{},[262,3718,3221],{},[24,3720,3721],{},[262,3722,3232],{},[24,3724,3725],{},[262,3726,3689],{},[24,3728,3729],{},[262,3730,3731],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[24,3733,3734],{},"Re-paste the public key in GitHub if needed",[24,3736,3737],{},[262,3738,3739],{},"ssh -T git@github.com",[37,3741,2515,3742,3744,3745,3747,3748,3751],{},[262,3743,3221],{}," fails in Git Bash, use ",[262,3746,3228],{},", then repeat the ",[262,3749,3750],{},"ssh-add"," steps",[11,3753,3754,3756,3759],{"id":433,"level":14},[16,3755,436],{"id":433},[37,3757,3758],{},"You are done when all are true:",[21,3760,3761,3766,3773,3778,3781,3786,3789],{},[24,3762,3763,3765],{},[262,3764,1981],{}," works",[24,3767,3768,3770,3771],{},[262,3769,3689],{}," shows ",[262,3772,3106],{},[24,3774,3775,3777],{},[262,3776,3739],{}," names your GitHub account",[24,3779,3780],{},"Your private course repository exists on GitHub",[24,3782,3783,3785],{},[262,3784,375],{}," and your TA, if applicable, are invited as collaborators",[24,3787,3788],{},"Your local terminal is open to the cloned repository",[24,3790,3791,2671,3794,3797],{},[262,3792,3793],{},"git config user.name",[262,3795,3796],{},"git config user.email"," return your repo identity",[11,3799,3800,3802],{"id":1795,"level":14},[16,3801,1799],{"id":1798},[100,3803,3804,3832],{"gap":102,"left-width":103,"right-width":103},[105,3805,3806,3808,3814,3820,3826],{"v-slot:left":107},[361,3807,1807],{"id":1806},[37,3809,3810,3813],{},[122,3811,3812],{},"Git identity"," - commit name and email saved in repo config",[37,3815,3816,3819],{},[122,3817,3818],{},"SSH key pair"," - private key on your computer, public key in GitHub",[37,3821,3822,3825],{},[122,3823,3824],{},"SSH agent"," - background helper that makes your private key available",[37,3827,3828,3831],{},[122,3829,3830],{},"Clone"," - local copy of a GitHub repository",[105,3833,3834,3836],{"v-slot:right":107},[361,3835,1838],{"id":1795},[21,3837,3838,3845,3852,3859],{},[24,3839,3840],{},[41,3841,3844],{"href":3842,"rel":3843},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[45],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[24,3846,3847],{},[41,3848,3851],{"href":3849,"rel":3850},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[45],"GitHub Docs: Testing your SSH connection",[24,3853,3854],{},[41,3855,3858],{"href":3856,"rel":3857},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[45],"GitHub Docs: Create a repository",[24,3860,3861],{},[41,3862,3865],{"href":3863,"rel":3864},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[45],"GitHub Docs: Cloning a repository",[11,3867,3868,3870,3872],{"id":462,"level":14},[16,3869,465],{"id":462},[37,3871,1868],{},[21,3873,3874,3877,3880,3883,3886,3889,3895],{},[24,3875,3876],{},"Use the correct terminal for your operating system",[24,3878,3879],{},"Authenticate to GitHub with SSH",[24,3881,3882],{},"Find your private course repository on GitHub",[24,3884,3885],{},"Invite course collaborators",[24,3887,3888],{},"Open the local clone in the terminal",[24,3890,3891,3892],{},"Show repo-local Git identity with ",[262,3893,3894],{},"git config",[24,3896,3897],{},"Next: practice the Git commands used for course work",{"title":107,"searchDepth":489,"depth":489,"links":3899},[3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3916,3917,3918,3919,3920,3923,3924,3925],{"id":2855,"depth":489,"text":2858},{"id":2881,"depth":489,"text":2884},{"id":2899,"depth":489,"text":2902},{"id":2924,"depth":489,"text":2927},{"id":2937,"depth":489,"text":2940},{"id":2967,"depth":489,"text":2968},{"id":3004,"depth":489,"text":3005},{"id":3081,"depth":489,"text":3082},{"id":3129,"depth":489,"text":3130},{"id":3196,"depth":489,"text":3197},{"id":3272,"depth":489,"text":3273},{"id":3314,"depth":489,"text":3315,"children":3912},[3913,3914,3915],{"id":3340,"depth":501,"text":3341},{"id":3372,"depth":501,"text":3373},{"id":3410,"depth":501,"text":3411},{"id":3455,"depth":489,"text":3456},{"id":3489,"depth":489,"text":3490},{"id":3574,"depth":489,"text":3575},{"id":3646,"depth":489,"text":3647},{"id":3672,"depth":489,"text":3675,"children":3921},[3922],{"id":3709,"depth":501,"text":3710},{"id":433,"depth":489,"text":436},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":2850,"description":3926},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[2173,3936,3937,3938],"github","ssh","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":3945,"title":3946,"audience":6,"body":3947,"contentType":505,"course":506,"description":4867,"estimateBasis":4868,"estimatedDiscussionMinutes":510,"estimatedLiveMinutes":3929,"estimatedTotalMinutes":4869,"extension":512,"meta":4870,"module":514,"navigation":515,"order":4871,"path":4872,"promptAssist":518,"seo":4873,"status":520,"stem":4874,"tags":4875,"videoDuration":4878,"videoId":4879,"videoLink":4880,"videoTitle":4881,"week":514,"__hash__":4882},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":3948,"toc":4832},[3949,3978,3999,4016,4048,4082,4133,4149,4170,4201,4233,4275,4306,4341,4365,4410,4437,4467,4485,4497,4533,4566,4602,4636,4662,4690,4720,4787,4829],[11,3950,3952,3955,3958],{"id":3951,"level":14},"objectives",[16,3953,3954],{"id":3951},"Objectives",[37,3956,3957],{},"By the end, you should be able to:",[21,3959,3960,3963,3966,3969,3972,3975],{},[24,3961,3962],{},"Explain what the common Git commands do",[24,3964,3965],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[24,3967,3968],{},"Create a branch for practice work",[24,3970,3971],{},"Stage, commit, and push a small change",[24,3973,3974],{},"Open a pull request on GitHub",[24,3976,3977],{},"Investigate a failed push and a merge conflict",[11,3979,3981,3985,3988,3991],{"id":3980,"level":14},"git-vs-github",[16,3982,3984],{"id":3983},"git-versus-github","Git Versus GitHub",[37,3986,3987],{},"Git is the tool that tracks file history",[37,3989,3990],{},"GitHub is a website that hosts a remote copy of a Git repository",[21,3992,3993,3996],{},[24,3994,3995],{},"Git: local terminal workflow",[24,3997,3998],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,4000,4002,4006,4010,4013],{"id":4001,"level":14},"git-stages",[16,4003,4005],{"id":4004},"the-git-stages","The Git Stages",[1227,4007],{"language":4008,"src":4009},"text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[37,4011,4012],{},"Common commands:",[1227,4014],{"language":4008,"src":4015},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,4017,4019,4023,4025,4028,4031,4034],{"id":4018,"level":14},"status-first",[16,4020,4022],{"id":4021},"command-1-git-status","Command 1: git status",[37,4024,1225],{},[1227,4026],{"language":1229,"src":4027},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[37,4029,4030],{},"Use this before and after every important Git action",[37,4032,4033],{},"It tells you:",[21,4035,4036,4039,4042,4045],{},[24,4037,4038],{},"Current branch",[24,4040,4041],{},"Changed files",[24,4043,4044],{},"Staged files",[24,4046,4047],{},"Whether your working tree is clean",[11,4049,4051,4055,4057,4060],{"id":4050,"level":14},"branch-command",[16,4052,4054],{"id":4053},"command-2-git-branch","Command 2: git branch",[37,4056,1225],{},[1227,4058],{"language":1229,"src":4059},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[21,4061,4062,4065,4068],{},[24,4063,4064],{},"Active branch has an asterisk",[24,4066,4067],{},"Branches are separate timelines for work",[24,4069,4070,4071],{},"Branch names are case-sensitive\n",[21,4072,4073],{},[24,4074,4075,2671,4078,4081],{},[262,4076,4077],{},"Practice",[262,4079,4080],{},"practice"," are different names",[11,4083,4085,4089,4094,4097],{"id":4084,"level":14},"create-branch",[16,4086,4088],{"id":4087},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[37,4090,4091,4092,1601],{},"Start from ",[262,4093,2138],{},[1227,4095],{"language":1229,"src":4096},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[21,4098,4099,4110],{},[24,4100,4101,4102,4104,4105],{},"First two commands: make sure ",[262,4103,2138],{}," is current\n",[21,4106,4107],{},[24,4108,4109],{},"Explained more later",[24,4111,4112,4113],{},"Branch control commands\n",[21,4114,4115,4121,4127],{},[24,4116,4117,4120],{},[262,4118,4119],{},"git checkout -b practice",": create and switch",[24,4122,4123,4126],{},[262,4124,4125],{},"git branch practice",": create only",[24,4128,4129,4132],{},[262,4130,4131],{},"git checkout practice",": switch to existing",[11,4134,4136,4140,4143,4146],{"id":4135,"level":14},"make-file",[16,4137,4139],{"id":4138},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[37,4141,4142],{},"Create a small practice file:",[1227,4144],{"language":1229,"src":4145},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[37,4147,4148],{},"Expected result: Git shows the new file as untracked",[11,4150,4152,4156,4159,4162,4165],{"id":4151,"level":14},"add-command",[16,4153,4155],{"id":4154},"command-3-git-add","Command 3: git add",[37,4157,4158],{},"Stage the new file:",[1227,4160],{"language":1229,"src":4161},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[37,4163,4164],{},"Staging means: include this change in the next commit",[21,4166,4167],{},[24,4168,4169],{},"See below for add patterns and verification checks",[11,4171,4173,4177,4180,4183],{"id":4172,"level":95},"add-variants",[361,4174,4176],{"id":4175},"common-git-add-patterns","Common git add Patterns",[37,4178,4179],{},"Use the smallest clear target when possible",[1227,4181],{"language":1229,"src":4182},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[21,4184,4185,4188,4191],{},[24,4186,4187],{},"Single file: safest when you changed one file",[24,4189,4190],{},"Folder: useful when one feature is grouped in one folder",[24,4192,4193,4196,4197,4200],{},[262,4194,4195],{},"git add .",": convenient, but review ",[262,4198,4199],{},"git status"," first",[11,4202,4204,4208,4211,4214],{"id":4203,"level":14},"diff-command",[16,4205,4207],{"id":4206},"command-4-git-diff","Command 4: git diff",[37,4209,4210],{},"Before committing, inspect what changed:",[1227,4212],{"language":1229,"src":4213},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[21,4215,4216,4223,4226,4231],{},[24,4217,4218,4219,4222],{},"New untracked file: ",[262,4220,4221],{},"git diff"," may show nothing",[24,4224,4225],{},"That does not mean the file is missing",[24,4227,1493,4228,4230],{},[262,4229,4199],{}," to confirm untracked files",[24,4232,1663],{},[11,4234,4236,4240,4243,4246,4249,4252],{"id":4235,"level":95},"cached-rm",[361,4237,4239],{"id":4238},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[37,4241,4242],{},"If a file was staged by mistake, remove it from staging:",[1227,4244],{"language":1229,"src":4245},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[37,4247,4248],{},"For a folder:",[1227,4250],{"language":1229,"src":4251},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[21,4253,4254,4265],{},[24,4255,4256,4259,4260],{},[262,4257,4258],{},"--cached",": remove from staging only\n",[21,4261,4262],{},[24,4263,4264],{},"Keeps the file in your working folder",[24,4266,4267,4269,4270],{},[262,4268,968],{},": folder mode\n",[21,4271,4272],{},[24,4273,4274],{},"Recursive: include files inside the folder",[11,4276,4278,4282,4285,4288,4291],{"id":4277,"level":14},"commit-command",[16,4279,4281],{"id":4280},"command-5-git-commit","Command 5: git commit",[37,4283,4284],{},"Commit the staged file:",[1227,4286],{"language":1229,"src":4287},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[37,4289,4290],{},"A commit is a saved checkpoint in your local repository",[21,4292,4293,4304],{},[24,4294,4295,4298,4299],{},[262,4296,4297],{},"-m",": commit message",[21,4300,4301],{},[24,4302,4303],{},"Required, even if the message is an empty string",[24,4305,1663],{},[11,4307,4309,4313,4315,4318,4338],{"id":4308,"level":95},"log-command",[361,4310,4312],{"id":4311},"check-the-local-history","Check The Local History",[37,4314,1225],{},[1227,4316],{"language":1229,"src":4317},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[21,4319,4320,4326,4332],{},[24,4321,4322,4325],{},[262,4323,4324],{},"log",": show commit history",[24,4327,4328,4331],{},[262,4329,4330],{},"--oneline",": one commit per line",[24,4333,4334,4337],{},[262,4335,4336],{},"-5",": show the latest five commits",[37,4339,4340],{},"You should see your latest commit near the top",[11,4342,4344,4348,4351,4354],{"id":4343,"level":14},"push-command",[16,4345,4347],{"id":4346},"command-6-git-push","Command 6: git push",[37,4349,4350],{},"Send the branch to GitHub:",[1227,4352],{"language":1229,"src":4353},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[21,4355,4356,4362],{},[24,4357,4358,4361],{},[262,4359,4360],{},"origin",": common remote name for GitHub",[24,4363,4364],{},"Final part: branch you are pushing",[11,4366,4368,4372],{"id":4367,"level":14},"open-pr",[16,4369,4371],{"id":4370},"pull-request","Pull Request",[100,4373,4374,4402],{"gap":102,"left-width":103,"right-width":103},[105,4375,4376,4379,4382,4385,4388,4391],{"v-slot:left":107},[37,4377,4378],{},"On GitHub, open a pull request",[37,4380,4381],{},"Use this direction:",[1227,4383],{"language":4008,"src":4384},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[37,4386,4387],{},"Use a clear description:",[1227,4389],{"language":4008,"src":4390},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[21,4392,4393,4396,4399],{},[24,4394,4395],{},"Review page before merge",[24,4397,4398],{},"Shows what will change",[24,4400,4401],{},"Captures branch evidence",[105,4403,4404],{"v-slot:right":107},[37,4405,4406],{},[140,4407],{"alt":4408,"src":4409,"variant":144},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,4411,4413,4417,4420,4428,4431,4434],{"id":4412,"level":14},"merge-pr",[16,4414,4416],{"id":4415},"merge-and-sync","Merge And Sync",[37,4418,4419],{},"After GitHub merge:",[21,4421,4422],{},[24,4423,4424,4425,4427],{},"Local ",[262,4426,2138],{}," is not updated automatically",[37,4429,4430],{},"Sync it:",[1227,4432],{"language":1229,"src":4433},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[37,4435,4436],{},"Remote changes must be pulled down intentionally",[11,4438,4440,4444,4447,4464],{"id":4439,"level":14},"why-prs",[16,4441,4443],{"id":4442},"why-pull-requests-matter","Why Pull Requests Matter",[37,4445,4446],{},"Pull requests create evidence:",[21,4448,4449,4452,4455,4458,4461],{},[24,4450,4451],{},"Which branch changed",[24,4453,4454],{},"Which files changed",[24,4456,4457],{},"What discussion or explanation was provided",[24,4459,4460],{},"Chance to review risky changes before merging",[24,4462,4463],{},"When the change was merged",[37,4465,4466],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,4468,4470,4474,4477],{"id":4469,"level":14},"exploration-intro",[16,4471,4473],{"id":4472},"troubleshooting-explorations","Troubleshooting Explorations",[37,4475,4476],{},"The next slides use controlled problems to practice recovery",[21,4478,4479,4482],{},[24,4480,4481],{},"The goal is not avoiding every error",[24,4483,4484],{},"The goal is reading output, identifying state, and recovering without guessing",[11,4486,4488,4491,4494],{"id":4487,"level":14},"exploration-setup",[16,4489,4490],{"id":4487},"Exploration Setup",[37,4492,4493],{},"Create a conflict practice branch:",[1227,4495],{"language":1229,"src":4496},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,4498,4500,4504,4510,4517,4522,4525,4528],{"id":4499,"level":14},"exploration-issue-1",[16,4501,4503],{"id":4502},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[37,4505,4506,4507],{},"On GitHub, switch to ",[262,4508,4509],{},"practice-conflict",[37,4511,4512,4513,4516],{},"Edit one line in ",[262,4514,4515],{},"myFile.txt"," directly on GitHub and commit the change",[21,4518,4519],{},[24,4520,4521],{},"Use the same line you will change locally",[37,4523,4524],{},"Back locally, edit that same line and commit:",[1227,4526],{"language":1229,"src":4527},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[21,4529,4530],{},[24,4531,4532],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,4534,4536,4540,4543],{"id":4535,"level":95},"issue-1-push-without-pulling",[361,4537,4539],{"id":4538},"try-push-without-pulling","Try Push Without Pulling",[37,4541,4542],{},"Push the local commit before pulling the GitHub commit:",[100,4544,4545,4558],{"gap":102,"left-width":103,"right-width":103},[105,4546,4547,4550],{"v-slot:left":107},[1227,4548],{"language":1229,"src":4549},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[21,4551,4552,4555],{},[24,4553,4554],{},"Expected result: push rejected",[24,4556,4557],{},"Reason: GitHub has a commit your local branch does not have",[105,4559,4560],{"v-slot:right":107},[37,4561,4562],{},[140,4563],{"alt":4564,"src":4565,"variant":144},"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,4567,4569,4573],{"id":4568,"level":95},"issue-1-read-output",[361,4570,4572],{"id":4571},"pull-the-remote-change","Pull The Remote Change",[100,4574,4575,4594],{"gap":102,"left-width":103,"right-width":103},[105,4576,4577,4580,4583,4586,4591],{"v-slot:left":107},[37,4578,4579],{},"The usual next command is:",[1227,4581],{"language":1229,"src":4582},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[37,4584,4585],{},"If Git asks how to reconcile divergent branches:",[21,4587,4588],{},[24,4589,4590],{},"Use merge behavior for this course practice",[1227,4592],{"language":1229,"src":4593},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[105,4595,4596],{"v-slot:right":107},[37,4597,4598],{},[140,4599],{"alt":4600,"src":4601,"variant":144},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,4603,4605,4609,4612,4616,4619,4622,4625],{"id":4604,"level":14},"exploration-issue-2",[16,4606,4608],{"id":4607},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[37,4610,4611],{},"After pulling, Git should report a conflict",[37,4613,3397,4614],{},[262,4615,4515],{},[37,4617,4618],{},"You may see markers like:",[1227,4620],{"language":4008,"src":4621},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[37,4623,4624],{},"Conflict markers show:",[21,4626,4627,4630,4633],{},[24,4628,4629],{},"Your local version",[24,4631,4632],{},"The GitHub version",[24,4634,4635],{},"The part Git could not combine automatically",[11,4637,4639,4643,4649,4652,4655,4658],{"id":4638,"level":95},"resolve-conflict",[361,4640,4642],{"id":4641},"resolve-the-conflict","Resolve The Conflict",[37,4644,4645,4646,4648],{},"Edit ",[262,4647,4515],{}," so it contains the final text you want",[37,4650,4651],{},"Remove all conflict markers",[37,4653,4654],{},"Then run:",[1227,4656],{"language":1229,"src":4657},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[21,4659,4660],{},[24,4661,1663],{},[11,4663,4665,4669,4672],{"id":4664,"level":95},"verify-conflict-resolution",[361,4666,4668],{"id":4667},"verify-the-recovery","Verify The Recovery",[37,4670,4671],{},"Check:",[21,4673,4674,4679,4682,4687],{},[24,4675,4676,4678],{},[262,4677,4199],{}," is clean",[24,4680,4681],{},"GitHub shows the updated branch",[24,4683,4684,4686],{},[262,4685,4515],{}," contains the final text",[24,4688,4689],{},"No conflict markers remain",[11,4691,4692,4694],{"id":1715,"level":14},[16,4693,1718],{"id":1715},[21,4695,4696,4699,4702,4705,4708,4717],{},[24,4697,4698],{},"Committing on the wrong branch",[24,4700,4701],{},"Forgetting to push after committing",[24,4703,4704],{},"Forgetting to pull after merging on GitHub",[24,4706,4707],{},"Leaving conflict markers in a file",[24,4709,4710,4711,1544,4714],{},"Using vague branch names like ",[262,4712,4713],{},"stuff",[262,4715,4716],{},"final",[24,4718,4719],{},"Making several unrelated changes in one commit",[11,4721,4722,4724],{"id":1795,"level":14},[16,4723,1799],{"id":1798},[100,4725,4726,4750],{"gap":102,"left-width":103,"right-width":103},[105,4727,4728,4730],{"v-slot:left":107},[361,4729,1807],{"id":1806},[21,4731,4732,4735,4738,4741,4744,4747],{},[24,4733,4734],{},"Working folder: files you can edit",[24,4736,4737],{},"Staging area: changes selected for the next commit",[24,4739,4740],{},"Commit: local saved checkpoint",[24,4742,4743],{},"Remote: GitHub copy of the repository",[24,4745,4746],{},"Pull request: GitHub page for reviewing and merging branch work",[24,4748,4749],{},"Conflict: a change Git cannot merge automatically",[105,4751,4752,4754],{"v-slot:right":107},[361,4753,1838],{"id":1795},[21,4755,4756,4764,4771,4779],{},[24,4757,4758,4759],{},"Pro Git Book: ",[41,4760,4763],{"href":4761,"rel":4762},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[45],"Git Basics",[24,4765,4758,4766],{},[41,4767,4770],{"href":4768,"rel":4769},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[45],"Basic Branching and Merging",[24,4772,4773,4774],{},"GitHub Docs: ",[41,4775,4778],{"href":4776,"rel":4777},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[45],"Creating a pull request",[24,4780,4781,4782],{},"Oh Shit, Git!?!: ",[41,4783,4786],{"href":4784,"rel":4785},"https:\u002F\u002Fohshitgit.com\u002F",[45],"Common Git recovery situations",[11,4788,4789,4791],{"id":462,"level":14},[16,4790,465],{"id":462},[100,4792,4795,4819],{"gap":512,"left-width":4793,"right-width":4794},"0.72fr","1.38fr",[105,4796,4797,4799],{"v-slot:left":107},[37,4798,1868],{},[21,4800,4801,4807,4810,4813,4816],{},[24,4802,4803,4804,4806],{},"Read ",[262,4805,4199],{}," before choosing the next command",[24,4808,4809],{},"Move a change from working folder to staging area to commit",[24,4811,4812],{},"Push a branch to GitHub and open a pull request",[24,4814,4815],{},"Recognize when a failed push or conflict needs recovery",[24,4817,4818],{},"Next: open the cloned repository in VS Code",[105,4820,4821,4824],{"v-slot:right":107},[37,4822,4823],{},"Git\u002FGitHub flow:",[4825,4826],"figure-image",{"alt":4827,"src":4828},"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",[37,4830,4831],{},"::",{"title":107,"searchDepth":489,"depth":489,"links":4833},[4834,4835,4836,4837,4838,4839,4840,4841,4844,4847,4850,4851,4852,4853,4854,4855,4856,4860,4864,4865,4866],{"id":3951,"depth":489,"text":3954},{"id":3983,"depth":489,"text":3984},{"id":4004,"depth":489,"text":4005},{"id":4021,"depth":489,"text":4022},{"id":4053,"depth":489,"text":4054},{"id":4087,"depth":489,"text":4088},{"id":4138,"depth":489,"text":4139},{"id":4154,"depth":489,"text":4155,"children":4842},[4843],{"id":4175,"depth":501,"text":4176},{"id":4206,"depth":489,"text":4207,"children":4845},[4846],{"id":4238,"depth":501,"text":4239},{"id":4280,"depth":489,"text":4281,"children":4848},[4849],{"id":4311,"depth":501,"text":4312},{"id":4346,"depth":489,"text":4347},{"id":4370,"depth":489,"text":4371},{"id":4415,"depth":489,"text":4416},{"id":4442,"depth":489,"text":4443},{"id":4472,"depth":489,"text":4473},{"id":4487,"depth":489,"text":4490},{"id":4502,"depth":489,"text":4503,"children":4857},[4858,4859],{"id":4538,"depth":501,"text":4539},{"id":4571,"depth":501,"text":4572},{"id":4607,"depth":489,"text":4608,"children":4861},[4862,4863],{"id":4641,"depth":501,"text":4642},{"id":4667,"depth":501,"text":4668},{"id":1715,"depth":489,"text":1718},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":3946,"description":4867},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[2173,4876,4877],"branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":4884,"title":4885,"audience":6,"body":4886,"contentType":505,"course":506,"description":5658,"estimateBasis":5659,"estimatedDiscussionMinutes":509,"estimatedLiveMinutes":511,"estimatedTotalMinutes":4871,"extension":512,"meta":5660,"module":514,"navigation":515,"order":5661,"path":5662,"promptAssist":518,"seo":5663,"status":520,"stem":5664,"tags":5665,"videoDuration":5669,"videoId":5670,"videoLink":5671,"videoTitle":5672,"week":514,"__hash__":5673},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":4887,"toc":5636},[4888,4905,4923,4944,4969,5004,5036,5114,5191,5293,5321,5386,5463,5487,5514,5532,5556,5607],[11,4889,4891,4894],{"id":4890,"level":14},"local-development-environment-title",[16,4892,4885],{"id":4893},"local-development-environment-setup",[21,4895,4896,4899,4902],{},[24,4897,4898],{},"VS Code for editing course files",[24,4900,4901],{},"Course profile for Internet Applications extensions",[24,4903,4904],{},"Optional local PHP check on your own computer",[11,4906,4907,4909],{"id":944,"level":14},[16,4908,947],{"id":944},[21,4910,4911,4914,4917,4920],{},[24,4912,4913],{},"Install VS Code",[24,4915,4916],{},"Open the course repository root",[24,4918,4919],{},"Install the required extensions for the course",[24,4921,4922],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,4924,4926,4929],{"id":4925,"level":14},"what-this-setup-does",[16,4927,4928],{"id":4925},"What This Setup Does",[21,4930,4931,4934,4937],{},[24,4932,4933],{},"VS Code: editor for course files",[24,4935,4936],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[24,4938,4939,4940,4943],{},"Optional host PHP: quick ",[262,4941,4942],{},"php -v"," check and editor support",[11,4945,4947,4950],{"id":4946,"level":14},"step-1-install-vs-code",[16,4948,4949],{"id":4946},"Step 1: Install VS Code",[21,4951,4952,4960,4963,4966],{},[24,4953,4954,4955],{},"Download: ",[41,4956,4959],{"href":4957,"rel":4958},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[45],"Visual Studio Code",[24,4961,4962],{},"Install like a normal desktop app",[24,4964,4965],{},"Do not install VS Code inside your repository folder",[24,4967,4968],{},"VS Code is the editor; the repo is the workspace folder",[11,4970,4972,4975,4978,5001],{"id":4971,"level":14},"step-2-open-the-repository",[16,4973,4974],{"id":4971},"Step 2: Open The Repository",[37,4976,4977],{},"After the course repo is cloned:",[21,4979,4980,4990,4993,4998],{},[24,4981,4982,4983,4986,4987],{},"VS Code -> ",[262,4984,4985],{},"File"," -> ",[262,4988,4989],{},"Open Folder",[24,4991,4992],{},"Choose the repository root",[24,4994,4995,4996],{},"Folder name should match ",[262,4997,3032],{},[24,4999,5000],{},"Trust the workspace only if it is your cloned GitHub repo",[37,5002,5003],{},"Do not open a ZIP copy or clone the same repo again",[11,5005,5007,5011,5033],{"id":5006,"level":14},"step-3-create-course-profile",[16,5008,5010],{"id":5009},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[21,5012,5013,5019,5027,5030],{},[24,5014,5015,5016],{},"Gear icon -> ",[262,5017,5018],{},"Profiles",[24,5020,5021,5022,1544,5024],{},"Create ",[262,5023,506],{},[262,5025,5026],{},"PHP",[24,5028,5029],{},"Switch into that profile",[24,5031,5032],{},"Install course extensions there",[37,5034,5035],{},"Profiles keep this course setup separate from other projects",[11,5037,5039,5042,5046],{"id":5038,"level":14},"step-4-install-extensions",[16,5040,5041],{"id":5038},"Step 4: Install Extensions",[361,5043,5045],{"id":5044},"start-with-these","Start With These",[21,5047,5048,5056,5064,5072,5080,5088,5103,5111],{},[24,5049,5050,5051],{},"Auto Rename Tag (Jun Han)\n",[21,5052,5053],{},[24,5054,5055],{},"Auto-completes matching HTML tags while you edit",[24,5057,5058,5059],{},"Bracket Lens (wraith13)\n",[21,5060,5061],{},[24,5062,5063],{},"Adds readability cues for closing brackets",[24,5065,5066,5067],{},"GitLens (GitKraken)\n",[21,5068,5069],{},[24,5070,5071],{},"Required: Git history, blame, and branch visibility in-editor",[24,5073,5074,5075],{},"MySQL (cweijan)\n",[21,5076,5077],{},[24,5078,5079],{},"Required later: connect to and inspect course database tables",[24,5081,5082,5083],{},"PHP Intelephense (Ben Mewburn)\n",[21,5084,5085],{},[24,5086,5087],{},"PHP language support, syntax checks, and warnings",[24,5089,5090,5091],{},"Todo Tree (Gruntfuggly)\n",[21,5092,5093],{},[24,5094,5095,5096,965,5099,5102],{},"Finds and lists ",[262,5097,5098],{},"TODO",[262,5100,5101],{},"FIXME",", and similar comments",[24,5104,5105,5106],{},"WakaTime\n",[21,5107,5108],{},[24,5109,5110],{},"Required in sections that use time tracking; needs your API key",[24,5112,5113],{},"See the slides below for MySQL and WakaTime setup",[11,5115,5117,5121],{"id":5116,"level":95},"step-4a-setup-mysql-extension",[16,5118,5120],{"id":5119},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[100,5122,5124,5183],{"gap":102,"left-width":2053,"right-width":2598,"align":5123},"center",[105,5125,5126,5130],{"v-slot:left":107},[361,5127,5129],{"id":5128},"connection-settings","Connection Settings",[21,5131,5132,5135,5180],{},[24,5133,5134],{},"Open the MySQL panel from the VS Code sidebar",[24,5136,5137,5138],{},"Create a new connection with your course database details",[21,5139,5140,5146,5152,5155,5158],{},[24,5141,5142,5143],{},"Host: ",[262,5144,5145],{},"db.ethereallab.app",[24,5147,5148,5149],{},"Port: ",[262,5150,5151],{},"3306",[24,5153,5154],{},"Username: your UCID",[24,5156,5157],{},"Database: your UCID",[24,5159,5160,5161],{},"Password: from your generated connection string\n",[21,5162,5163,5171],{},[24,5164,5165,5166],{},"Get it from the ",[41,5167,5170],{"href":5168,"rel":5169},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[45],"course database page",[24,5172,5173,5174,2671,5177],{},"Use the 12 characters between ",[262,5175,5176],{},"ucid:",[262,5178,5179],{},"@",[24,5181,5182],{},"Save this connection; you will reuse it in later database lessons",[105,5184,5185],{"v-slot:right":107},[37,5186,5187],{},[140,5188],{"alt":5189,"src":5190,"variant":144},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,5192,5194,5198],{"id":5193,"level":95},"step-4b-setup-wakatime",[16,5195,5197],{"id":5196},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[100,5199,5201,5256],{"gap":102,"left-width":3008,"right-width":5200,"align":5123},"1.05fr",[105,5202,5203,5207],{"v-slot:left":107},[361,5204,5206],{"id":5205},"setup-order","Setup Order",[21,5208,5209,5216,5219,5222,5225,5228,5245,5250,5253],{},[24,5210,2027,5211],{},[41,5212,5215],{"href":5213,"rel":5214},"https:\u002F\u002Fwakatime.com\u002Fsignup",[45],"WakaTime",[24,5217,5218],{},"Create or open your account",[24,5220,5221],{},"Copy your API key from account settings",[24,5223,5224],{},"In VS Code, search Extensions for WakaTime",[24,5226,5227],{},"Install the WakaTime extension",[24,5229,5230,5231],{},"Open Command Palette:",[21,5232,5233,5239],{},[24,5234,5235,5236],{},"Windows\u002FLinux: ",[262,5237,5238],{},"Ctrl+Shift+P",[24,5240,5241,5242],{},"macOS: ",[262,5243,5244],{},"Cmd+Shift+P",[24,5246,2705,5247],{},[262,5248,5249],{},"WakaTime: API Key",[24,5251,5252],{},"Paste your API key",[24,5254,5255],{},"Restart VS Code if tracking does not appear right away",[105,5257,5258,5263,5270,5275,5282,5287],{"v-slot:right":107},[159,5259,5260],{},[24,5261,5262],{},"WakaTime account settings:",[37,5264,5265],{},[140,5266],{"alt":5267,"src":5268,"variant":144,"max-height":5269},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[159,5271,5272],{"start":489},[24,5273,5274],{},"VS Code extension search:",[37,5276,5277],{},[140,5278],{"alt":5279,"src":5280,"variant":144,"max-height":5281},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[159,5283,5284],{"start":501},[24,5285,5286],{},"VS Code API key command:",[37,5288,5289],{},[140,5290],{"alt":5291,"src":5292,"variant":144,"max-height":5281},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,5294,5296,5299],{"id":5295,"level":14},"step-5-optional-local-php",[16,5297,5298],{"id":5295},"Step 5: Optional Local PHP",[21,5300,5301,5304,5307,5315,5318],{},[24,5302,5303],{},"Useful for editor support",[24,5305,5306],{},"Useful for quick terminal checks",[24,5308,5309,5310],{},"Not the main course runtime\n",[21,5311,5312],{},[24,5313,5314],{},"Viable backup solution if VM lesson has issues",[24,5316,5317],{},"VM and Render still run the real app path",[24,5319,5320],{},"See the slides below for OS-specific install notes",[11,5322,5324,5327],{"id":5323,"level":95},"step-5a-windows-php-zip",[16,5325,5326],{"id":5323},"Step 5A: Windows PHP ZIP",[100,5328,5329,5360],{"gap":102,"left-width":103,"right-width":103},[105,5330,5331,5335],{"v-slot:left":107},[361,5332,5334],{"id":5333},"download-and-extract","Download And Extract",[21,5336,5337,5340,5350,5355],{},[24,5338,5339],{},"Download PHP for Windows as a ZIP",[24,5341,5342,5343],{},"Extract it outside your repository",[21,5344,5345],{},[24,5346,1118,5347],{},[262,5348,5349],{},"C:\\tools\\php",[24,5351,5352,5353],{},"Add that extracted PHP folder to the user ",[262,5354,1818],{},[24,5356,5357,5358],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[262,5359,1818],{},[105,5361,5362,5366,5382],{"v-slot:right":107},[361,5363,5365],{"id":5364},"visual-checks","Visual Checks",[21,5367,5368,5374,5379],{},[24,5369,5370,5371],{},"The extracted folder contains ",[262,5372,5373],{},"php.exe",[24,5375,5376,5377],{},"The Path entry points to the folder, not to ",[262,5378,5373],{},[24,5380,5381],{},"A new terminal can run:",[1227,5383],{"language":1229,"src":5384,"label":5385},"\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,5387,5389,5392],{"id":5388,"level":95},"step-5b-macos-homebrew-php",[16,5390,5391],{"id":5388},"Step 5B: macOS Homebrew PHP",[100,5393,5394,5425],{"gap":102,"left-width":103,"right-width":103},[105,5395,5396,5400],{"v-slot:left":107},[361,5397,5399],{"id":5398},"install-homebrew","Install Homebrew",[21,5401,5402,5405,5413,5416,5419,5422],{},[24,5403,5404],{},"Open Terminal",[24,5406,5407,5408],{},"Copy the install command from ",[41,5409,5412],{"href":5410,"rel":5411},"https:\u002F\u002Fbrew.sh\u002F",[45],"brew.sh",[24,5414,5415],{},"Expect Terminal to ask for your Mac password",[24,5417,5418],{},"Expect Homebrew to mention Command Line Tools if needed",[24,5420,5421],{},"At the end, Homebrew may print \"Next steps\"",[24,5423,5424],{},"Run those \"Next steps\" commands if shown",[105,5426,5427,5431,5435,5438],{"v-slot:right":107},[361,5428,5430],{"id":5429},"then-install-php","Then Install PHP",[1227,5432],{"language":1229,"src":5433,"label":5434},"\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",[37,5436,5437],{},"Look for:",[21,5439,5440,5446,5451,5457],{},[24,5441,5442,5445],{},[262,5443,5444],{},"brew --version"," prints a version",[24,5447,5448,5450],{},[262,5449,4942],{}," prints PHP 8 output",[24,5452,5453,5454],{},"Apple Silicon Macs commonly use ",[262,5455,5456],{},"\u002Fopt\u002Fhomebrew",[24,5458,5459,5460],{},"Intel Macs commonly use ",[262,5461,5462],{},"\u002Fusr\u002Flocal",[11,5464,5466,5470,5472,5476],{"id":5465,"level":95},"step-5c-linux-php-cli",[16,5467,5469],{"id":5468},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[37,5471,1225],{},[1227,5473],{"language":1229,"src":5474,"label":5475},"\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",[21,5477,5478,5481,5484],{},[24,5479,5480],{},"This installs command-line PHP",[24,5482,5483],{},"This is only for local terminal checks",[24,5485,5486],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,5488,5490,5493,5495,5498,5500,5503],{"id":5489,"level":14},"step-6-verify-optional-php",[16,5491,5492],{"id":5489},"Step 6: Verify Optional PHP",[37,5494,1225],{},[1227,5496],{"language":1229,"src":5497},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[37,5499,3097],{},[1227,5501],{"language":4008,"src":5502},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[21,5504,5505,5508,5511],{},[24,5506,5507],{},"Exact version can differ",[24,5509,5510],{},"PHP 8 output means the terminal can find PHP",[24,5512,5513],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,5515,5516,5518],{"id":1715,"level":14},[16,5517,1718],{"id":1715},[21,5519,5520,5523,5526,5529],{},[24,5521,5522],{},"Installing tools inside the repository folder",[24,5524,5525],{},"Opening the parent folder instead of the repo root",[24,5527,5528],{},"Editing a ZIP copy instead of the cloned repo",[24,5530,5531],{},"Installing extensions in the wrong VS Code profile",[11,5533,5534,5536],{"id":433,"level":14},[16,5535,436],{"id":433},[21,5537,5538,5541,5544,5547,5550],{},[24,5539,5540],{},"VS Code opens your course repository root",[24,5542,5543],{},"Course profile is active",[24,5545,5546],{},"PHP Intelephense is installed",[24,5548,5549],{},"GitLens is installed",[24,5551,5552,5553,5555],{},"Optional: ",[262,5554,4942],{}," prints a PHP 8 version",[11,5557,5558,5560],{"id":1798,"level":14},[16,5559,1799],{"id":1798},[100,5561,5562,5580],{"gap":102,"left-width":103,"right-width":103},[105,5563,5564,5566],{"v-slot:left":107},[361,5565,1807],{"id":1806},[21,5567,5568,5571,5574,5577],{},[24,5569,5570],{},"IDE: editor with development tools",[24,5572,5573],{},"Extension: add-on that changes VS Code behavior",[24,5575,5576],{},"Profile: saved VS Code setup",[24,5578,5579],{},"PATH: system setting used to find commands",[105,5581,5582,5584],{"v-slot:right":107},[361,5583,1838],{"id":1795},[21,5585,5586,5593,5600],{},[24,5587,5588],{},[41,5589,5592],{"href":5590,"rel":5591},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[45],"VS Code Getting Started",[24,5594,5595],{},[41,5596,5599],{"href":5597,"rel":5598},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[45],"VS Code Profiles",[24,5601,5602],{},[41,5603,5606],{"href":5604,"rel":5605},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[45],"PHP Installation",[11,5608,5609,5611],{"id":462,"level":14},[16,5610,465],{"id":462},[21,5612,5613,5616,5619,5622,5633],{},[24,5614,5615],{},"VS Code installed as the course editor",[24,5617,5618],{},"Repository opens from its root folder",[24,5620,5621],{},"Course extensions live in a course profile",[24,5623,5624,5625],{},"Local PHP is optional for this Internet Applications path\n",[21,5626,5627,5630],{},[24,5628,5629],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[24,5631,5632],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[24,5634,5635],{},"Next: copy the instructor template into the repository",{"title":107,"searchDepth":489,"depth":489,"links":5637},[5638,5639,5640,5641,5642,5643,5644,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657],{"id":4893,"depth":489,"text":4885},{"id":944,"depth":489,"text":947},{"id":4925,"depth":489,"text":4928},{"id":4946,"depth":489,"text":4949},{"id":4971,"depth":489,"text":4974},{"id":5009,"depth":489,"text":5010},{"id":5038,"depth":489,"text":5041,"children":5645},[5646],{"id":5044,"depth":501,"text":5045},{"id":5119,"depth":489,"text":5120},{"id":5196,"depth":489,"text":5197},{"id":5295,"depth":489,"text":5298},{"id":5323,"depth":489,"text":5326},{"id":5388,"depth":489,"text":5391},{"id":5468,"depth":489,"text":5469},{"id":5489,"depth":489,"text":5492},{"id":1715,"depth":489,"text":1718},{"id":433,"depth":489,"text":436},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":4885,"description":5658},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[5666,5667,5668],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":5675,"title":5676,"audience":6,"body":5677,"contentType":505,"course":506,"description":6728,"estimateBasis":6729,"estimatedDiscussionMinutes":3928,"estimatedLiveMinutes":1945,"estimatedTotalMinutes":6730,"extension":512,"meta":6731,"module":514,"navigation":515,"order":6730,"path":6732,"promptAssist":518,"seo":6733,"status":520,"stem":6734,"tags":6735,"videoDuration":6736,"videoId":6737,"videoLink":6738,"videoTitle":6739,"week":514,"__hash__":6740},"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":5678,"toc":6700},[5679,5708,5750,5778,5811,5842,5888,5981,6025,6070,6115,6160,6232,6291,6364,6418,6494,6563,6595,6647,6671],[11,5680,5681,5683,5686],{"id":3951,"level":14},[16,5682,3954],{"id":3951},[37,5684,5685],{},"By the end, you should have:",[21,5687,5688,5691,5694,5700,5705],{},[24,5689,5690],{},"Cloned course repository open in the terminal",[24,5692,5693],{},"Starter template copied into the repository root",[24,5695,5696,5697],{},"Baseline commit on ",[262,5698,5699],{},"Module01-Course-Template",[24,5701,5702,5703],{},"Pull request merged into ",[262,5704,2138],{},[24,5706,5707],{},"Clean working tree before moving on",[11,5709,5711,5715],{"id":5710,"level":14},"step-1-open-clone",[16,5712,5714],{"id":5713},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[100,5716,5717,5725],{"gap":102,"left-width":103,"right-width":103},[105,5718,5719,5721],{"v-slot:left":107},[37,5720,1225],{},[1227,5722],{"language":1229,"src":5723,"label":5724},"\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",[105,5726,5727,5729,5732],{"v-slot:right":107},[37,5728,3097],{},[1227,5730],{"language":2571,"src":5731,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[21,5733,5734,5739,5744],{},[24,5735,5736,5738],{},[262,5737,1035],{},": current working directory",[24,5740,5741,5743],{},[262,5742,4199],{},": current branch and file state",[24,5745,5746,5747,5749],{},"Important check: ",[262,5748,1035],{}," ends with your repository folder",[11,5751,5753,5757,5760,5763],{"id":5752,"level":14},"step-2-open-vscode",[16,5754,5756],{"id":5755},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[37,5758,5759],{},"Run from inside the cloned repository folder:",[1227,5761],{"language":1229,"src":5762},"\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",[21,5764,5765,5770,5775],{},[24,5766,5767,5769],{},[262,5768,262],{},": opens VS Code from the terminal",[24,5771,5772,5774],{},[262,5773,1100],{}," means \"this current folder\"",[24,5776,5777],{},"VS Code should show your repository folder, not the parent folder",[11,5779,5781,5785],{"id":5780,"level":14},"step-3-download-template",[16,5782,5784],{"id":5783},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[21,5786,5787,5799,5802,5805,5808],{},[24,5788,5789,5790],{},"Open the instructor template repository",[21,5791,5792],{},[24,5793,5794],{},[41,5795,5798],{"href":5796,"rel":5797},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[45],"IT202-2026",[24,5800,5801],{},"Download the ZIP",[24,5803,5804],{},"Extract the ZIP",[24,5806,5807],{},"Copy scaffold contents into your repository root",[24,5809,5810],{},"See the slide below for the copy rule",[11,5812,5814,5818,5821,5824,5839],{"id":5813,"level":95},"template-copy-rule",[361,5815,5817],{"id":5816},"copy-rule","Copy Rule",[37,5819,5820],{},"Copy the contents of the extracted template folder",[37,5822,5823],{},"Do not copy:",[21,5825,5826,5829,5836],{},[24,5827,5828],{},"The extracted wrapper folder as one extra nested folder",[24,5830,5831,5832,5835],{},"The template repository's hidden ",[262,5833,5834],{},".git"," folder",[24,5837,5838],{},"Old files from a different semester",[37,5840,5841],{},"Repository root should contain the starter folders directly",[11,5843,5845,5849,5852,5855],{"id":5844,"level":14},"step-4-check-structure",[16,5846,5848],{"id":5847},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[37,5850,5851],{},"After copying, repository root should look similar to:",[1227,5853],{"language":4008,"src":5854},"\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",[21,5856,5857,5862,5871,5885],{},[24,5858,5859,5861],{},[262,5860,1167],{}," should be directly inside your repository root",[24,5863,5864,5865,5868,5869],{},"Module folders and ",[262,5866,5867],{},"project"," live inside ",[262,5870,1167],{},[24,5872,5873,965,5876,969,5879,5882,5883],{},[262,5874,5875],{},"lib",[262,5877,5878],{},"partials",[262,5880,5881],{},"sql"," stay outside ",[262,5884,1167],{},[24,5886,5887],{},"See the slide below for the public\u002Fprivate folder boundary",[11,5889,5891,5895,5978],{"id":5890,"level":95},"public-html-boundary",[361,5892,5894],{"id":5893},"public-and-private-boundary","Public And Private Boundary",[21,5896,5897,5931,5953,5958,5963,5969,5975],{},[24,5898,5899,5901,5902],{},[262,5900,1167],{},": web root Apache can serve\n",[21,5903,5904,5914,5919,5925],{},[24,5905,5906,5909,5910,5913],{},[262,5907,5908],{},"m01"," through ",[262,5911,5912],{},"m10",": module practice folders",[24,5915,5916,5918],{},[262,5917,5867],{},": course project folder",[24,5920,5921,5924],{},[262,5922,5923],{},"index.php",": first browser entry point",[24,5926,5927,5930],{},[262,5928,5929],{},"test_db.php",": database connection check",[24,5932,5933,5935,5936],{},[262,5934,5875],{},": reusable PHP helpers\n",[21,5937,5938,5944],{},[24,5939,5940,5943],{},[262,5941,5942],{},".env.sample",": example local config file",[24,5945,5946,2671,5949,5952],{},[262,5947,5948],{},"config.php",[262,5950,5951],{},"db.php",": config and database helpers",[24,5954,5955,5957],{},[262,5956,5878],{},": shared page pieces",[24,5959,5960,5962],{},[262,5961,5881],{},": database setup scripts",[24,5964,5965,5968],{},[262,5966,5967],{},"Dockerfile",": consistent runtime setup",[24,5970,5971,5974],{},[262,5972,5973],{},"structure.md",": starter layout notes",[24,5976,5977],{},"Private folders should not be opened directly in the browser",[37,5979,5980],{},"Later server setup expects this folder boundary",[11,5982,5984,5988],{"id":5983,"level":14},"step-5-check-status",[16,5985,5987],{"id":5986},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[100,5989,5990,5998],{"gap":102,"left-width":103,"right-width":103},[105,5991,5992,5994],{"v-slot:left":107},[37,5993,1225],{},[1227,5995],{"language":1229,"src":5996,"label":5997},"\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",[105,5999,6000,6003,6006],{"v-slot:right":107},[37,6001,6002],{},"Expected idea:",[1227,6004],{"language":4008,"src":6005,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[21,6007,6008,6014,6019,6022],{},[24,6009,6010,6013],{},[262,6011,6012],{},"git checkout -b",": create and move to a new branch",[24,6015,6016,6017],{},"Branch name: ",[262,6018,5699],{},[24,6020,6021],{},"New files listed as untracked",[24,6023,6024],{},"No changes means likely wrong folder or copy missed",[11,6026,6028,6032],{"id":6027,"level":14},"step-6-stage",[16,6029,6031],{"id":6030},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[100,6033,6034,6042],{"gap":102,"left-width":103,"right-width":103},[105,6035,6036,6038],{"v-slot:left":107},[37,6037,1225],{},[1227,6039],{"language":1229,"src":6040,"label":6041},"\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",[105,6043,6044,6047,6065,6067],{"v-slot:right":107},[37,6045,6046],{},"What this means:",[21,6048,6049,6055,6060],{},[24,6050,6051,6054],{},[262,6052,6053],{},"git add",": choose files for the next commit",[24,6056,6057,6059],{},[262,6058,1100],{}," means current folder and contents",[24,6061,6062,6064],{},[262,6063,4199],{},": verify what is staged before committing",[37,6066,6002],{},[1227,6068],{"language":4008,"src":6069,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,6071,6073,6077],{"id":6072,"level":14},"step-7-commit",[16,6074,6076],{"id":6075},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[100,6078,6079,6087],{"gap":102,"left-width":103,"right-width":103},[105,6080,6081,6083],{"v-slot:left":107},[37,6082,1225],{},[1227,6084],{"language":1229,"src":6085,"label":6086},"\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",[105,6088,6089,6091,6094],{"v-slot:right":107},[37,6090,6002],{},[1227,6092],{"language":4008,"src":6093,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[21,6095,6096,6102,6112],{},[24,6097,6098,6101],{},[262,6099,6100],{},"git commit",": save staged changes in local history",[24,6103,6104,6106,6107],{},[262,6105,4297],{},": commit message\n",[21,6108,6109],{},[24,6110,6111],{},"Message is required, even if empty",[24,6113,6114],{},"Baseline commit: starter state before custom work",[11,6116,6118,6122],{"id":6117,"level":14},"step-8-push",[16,6119,6121],{"id":6120},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[100,6123,6124,6132],{"gap":102,"left-width":103,"right-width":103},[105,6125,6126,6128],{"v-slot:left":107},[37,6127,1225],{},[1227,6129],{"language":1229,"src":6130,"label":6131},"\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",[105,6133,6134,6136,6139],{"v-slot:right":107},[37,6135,6002],{},[1227,6137],{"language":4008,"src":6138,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[21,6140,6141,6146,6152,6157],{},[24,6142,6143,6145],{},[262,6144,4360],{},": GitHub remote",[24,6147,6148,6151],{},[262,6149,6150],{},"-u",": remembers this branch's GitHub tracking branch",[24,6153,6154,6156],{},[262,6155,5699],{},": branch being sent",[24,6158,6159],{},"Refresh GitHub after the push",[11,6161,6163,6167],{"id":6162,"level":14},"step-9-open-pull-request",[16,6164,6166],{"id":6165},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[100,6168,6169,6212],{"gap":102,"left-width":103,"right-width":103},[105,6170,6171,6173],{"v-slot:left":107},[37,6172,3013],{},[21,6174,6175,6178,6194,6199,6204,6207],{},[24,6176,6177],{},"Open your course repository",[24,6179,166,6180,6183],{},[122,6181,6182],{},"Compare & pull request",[21,6184,6185],{},[24,6186,6187,6188,4986,6191],{},"Or use ",[122,6189,6190],{},"Pull requests",[122,6192,6193],{},"New pull request",[24,6195,6196,6197],{},"Set base branch to ",[262,6198,2138],{},[24,6200,6201,6202],{},"Set compare branch to ",[262,6203,5699],{},[24,6205,6206],{},"Confirm the changed files are the starter template files",[24,6208,166,6209],{},[122,6210,6211],{},"Create pull request",[105,6213,6214,6217,6221],{"v-slot:right":107},[37,6215,6216],{},"Use a short title and description:",[1227,6218],{"language":4008,"src":6219,"label":6220},"\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",[21,6222,6223,6226,6229],{},[24,6224,6225],{},"Base receives the changes",[24,6227,6228],{},"Compare contains your branch work",[24,6230,6231],{},"If base and compare are reversed, do not create the pull request",[11,6233,6235,6241],{"id":6234,"level":14},"step-10-merge-sync-main",[16,6236,6238,6239],{"id":6237},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[262,6240,2138],{},[100,6242,6243,6265],{"gap":102,"left-width":103,"right-width":103},[105,6244,6245,6247,6259,6261],{"v-slot:left":107},[37,6246,3013],{},[21,6248,6249,6254],{},[24,6250,166,6251],{},[122,6252,6253],{},"Merge pull request",[24,6255,166,6256],{},[122,6257,6258],{},"Confirm merge",[37,6260,4654],{},[1227,6262],{"language":1229,"src":6263,"label":6264},"\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",[105,6266,6267,6269,6272],{"v-slot:right":107},[37,6268,6002],{},[1227,6270],{"language":4008,"src":6271,"label":2957},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[21,6273,6274,6280,6286],{},[24,6275,6276,6279],{},[262,6277,6278],{},"git checkout main",": return to the main branch",[24,6281,6282,6285],{},[262,6283,6284],{},"git pull origin main",": download the merged template files",[24,6287,6288,6289,4678],{},"Continue only when local ",[262,6290,2138],{},[11,6292,6294,6300],{"id":6293,"level":14},"step-11-create-local-env",[16,6295,6296,6297],{"id":6293},"Step 11: Create Local ",[262,6298,6299],{},".env",[100,6301,6302,6324],{"gap":102,"left-width":103,"right-width":103},[105,6303,6304,6307,6311],{"v-slot:left":107},[37,6305,6306],{},"Run from the repository root:",[1227,6308],{"language":1229,"src":6309,"label":6310},"\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",[21,6312,6313],{},[24,6314,6315,6316,6319,6320],{},"Get ",[262,6317,6318],{},"DB_URL"," from ",[41,6321,6323],{"href":5168,"rel":6322},[45],"courses.ethereallab.app\u002Fdatabase",[105,6325,6326,6329,6334],{"v-slot:right":107},[37,6327,6328],{},"Fill in values similar to:",[1227,6330],{"language":6331,"src":6332,"label":6333},"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",[21,6335,6336,6341,6346,6349,6354,6359],{},[24,6337,6338,6340],{},[262,6339,6299],{}," stores local secrets",[24,6342,2072,6343,6345],{},[262,6344,6299],{}," on your computer only",[24,6347,6348],{},"Do not commit your real connection string",[24,6350,6351,6352],{},"Paste the generated database connection string as ",[262,6353,6318],{},[24,6355,6356,6358],{},[262,6357,5948],{}," loads local or hosted environment variables",[24,6360,6361,6362],{},"Do not paste secrets directly into ",[262,6363,5948],{},[11,6365,6367,6371],{"id":6366,"level":14},"step-12-test-local-db",[16,6368,6370],{"id":6369},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[100,6372,6373,6381],{"gap":102,"left-width":103,"right-width":103},[105,6374,6375,6377],{"v-slot:left":107},[37,6376,6306],{},[1227,6378],{"language":1229,"src":6379,"label":6380},"\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",[105,6382,6383,6386,6390],{"v-slot:right":107},[37,6384,6385],{},"Then open:",[1227,6387],{"language":4008,"src":6388,"label":6389},"\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",[21,6391,6392,6398,6404,6412],{},[24,6393,6394,6397],{},[262,6395,6396],{},"php -S",": starts PHP's built-in local server",[24,6399,6400,6403],{},[262,6401,6402],{},"-t public_html",": serves the course web root",[24,6405,6406,6408,6409,6411],{},[262,6407,5929],{},": confirms PHP can read ",[262,6410,6299],{}," and connect to MySQL",[24,6413,6414,6415,6417],{},"Stop the server with ",[262,6416,1770],{}," when finished",[11,6419,6421,6429,6435],{"id":6420,"level":14},"step-13-enable-pdo-mysql",[16,6422,6424,6425,6428],{"id":6423},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[262,6426,6427],{},"pdo_mysql"," If Needed",[37,6430,6431,6432,1100],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[262,6433,6434],{},"apt",[100,6436,6437,6468],{"gap":102,"left-width":103,"right-width":103},[105,6438,6439,6442,6446,6449],{"v-slot:left":107},[37,6440,6441],{},"Find the PHP folder:",[1227,6443],{"language":1229,"src":6444,"label":6445},"\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",[37,6447,6448],{},"In that folder:",[21,6450,6451,6457,6463],{},[24,6452,6453,6454],{},"Find ",[262,6455,6456],{},"php.ini-development",[24,6458,6459,6460],{},"Copy it as ",[262,6461,6462],{},"php.ini",[24,6464,3397,6465,6467],{},[262,6466,6462],{}," in your editor",[105,6469,6470,6473,6477,6480,6484],{"v-slot:right":107},[37,6471,6472],{},"Uncomment these lines:",[1227,6474],{"language":6475,"src":6476,"label":6462},"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",[37,6478,6479],{},"Mac\u002FLinux usually use:",[1227,6481],{"language":1229,"src":6482,"label":6483},"\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",[21,6485,6486,6491],{},[24,6487,6488,6489],{},"Restart the php dev server after changing ",[262,6490,6462],{},[24,6492,6493],{},"Run Step 12 again after enabling the extension",[11,6495,6497,6499,6502],{"id":6496,"level":14},"quick-check-final",[16,6498,436],{"id":433},[37,6500,6501],{},"Confirm all of these:",[21,6503,6504,6507,6515,6518,6523,6532,6538,6543,6548,6554],{},[24,6505,6506],{},"GitHub shows the starter files",[24,6508,6509,6510,6512,6513],{},"GitHub shows a pull request from ",[262,6511,5699],{}," into ",[262,6514,2138],{},[24,6516,6517],{},"The pull request is merged",[24,6519,4424,6520,6522],{},[262,6521,2138],{}," says the working tree is clean",[24,6524,6525,5909,6528,6531],{},[262,6526,6527],{},"public_html\u002Fm01",[262,6529,6530],{},"public_html\u002Fm10"," exist",[24,6533,6534,6537],{},[262,6535,6536],{},"public_html\u002Fproject"," exists",[24,6539,6540,6542],{},[262,6541,1167],{}," is not nested inside another accidental folder",[24,6544,6545,6547],{},[262,6546,6333],{}," exists locally and is not committed with real secrets",[24,6549,6550,6553],{},[262,6551,6552],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[24,6555,6556,6557,6559,6560,6562],{},"Windows PHP has ",[262,6558,6427],{}," enabled if ",[262,6561,5929],{}," reports a missing driver",[11,6564,6566,6570,6572,6575,6584],{"id":6565,"level":14},"reset-check",[16,6567,6569],{"id":6568},"if-something-looks-wrong","If Something Looks Wrong",[37,6571,1225],{},[1227,6573],{"language":1229,"src":6574},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[6576,6577,6578],"blockquote",{},[37,6579,6580,6581,6583],{},"Tip: ",[262,6582,3551],{}," prints the repository root when your current folder is inside a Git repository",[21,6585,6586,6589,6592],{},[24,6587,6588],{},"Output should point to your course repository",[24,6590,6591],{},"If it points somewhere else, move folders before continuing",[24,6593,6594],{},"Avoid cloning inside another cloned repository",[11,6596,6597,6599],{"id":1715,"level":14},[16,6598,1718],{"id":1715},[21,6600,6601,6604,6607,6612,6615,6618,6623,6633,6638,6641],{},[24,6602,6603],{},"Opening the parent folder instead of the repository root",[24,6605,6606],{},"Copying the instructor template folder as a nested folder",[24,6608,6609,6610,5835],{},"Copying the template ",[262,6611,5834],{},[24,6613,6614],{},"Keeping the downloaded ZIP inside the repository",[24,6616,6617],{},"Re-cloning the repository instead of opening the existing clone",[24,6619,6620,6621],{},"Putting module folders outside ",[262,6622,1167],{},[24,6624,6625,6626,6628,6629,6632],{},"Renaming ",[262,6627,5908],{}," to ",[262,6630,6631],{},"M1"," or mixing folder casing",[24,6634,6635,6636],{},"Doing template work directly on ",[262,6637,2138],{},[24,6639,6640],{},"Reversing base and compare branches in the pull request",[24,6642,6643,6644,6646],{},"Forgetting to sync local ",[262,6645,2138],{}," after the pull request is merged",[11,6648,6649,6651],{"id":1806,"level":14},[16,6650,1807],{"id":1806},[21,6652,6653,6656,6659,6662,6665,6668],{},[24,6654,6655],{},"Repository root: top folder of the cloned project",[24,6657,6658],{},"Baseline: starter state before custom work begins",[24,6660,6661],{},"Pull request: GitHub review page used to merge branch work",[24,6663,6664],{},"Web root: folder served to the browser",[24,6666,6667],{},"Scaffold: starter folders that organize future work",[24,6669,6670],{},"Staging: choosing files for the next commit",[11,6672,6673,6675,6678],{"id":462,"level":14},[16,6674,465],{"id":462},[37,6676,6677],{},"Before leaving this presentation, confirm the following:",[21,6679,6680,6683,6686,6689,6695],{},[24,6681,6682],{},"You still have one clone for your repository",[24,6684,6685],{},"Your VS Code is able to open directly to your repository",[24,6687,6688],{},"Your repository has the full starter baseline correctly structured",[24,6690,6691,6692,6694],{},"GitHub remote ",[262,6693,2138],{}," has the baseline content",[24,6696,4424,6697,6699],{},[262,6698,2138],{}," was synchronized",{"title":107,"searchDepth":489,"depth":489,"links":6701},[6702,6703,6704,6705,6708,6711,6712,6713,6714,6715,6716,6718,6720,6721,6723,6724,6725,6726,6727],{"id":3951,"depth":489,"text":3954},{"id":5713,"depth":489,"text":5714},{"id":5755,"depth":489,"text":5756},{"id":5783,"depth":489,"text":5784,"children":6706},[6707],{"id":5816,"depth":501,"text":5817},{"id":5847,"depth":489,"text":5848,"children":6709},[6710],{"id":5893,"depth":501,"text":5894},{"id":5986,"depth":489,"text":5987},{"id":6030,"depth":489,"text":6031},{"id":6075,"depth":489,"text":6076},{"id":6120,"depth":489,"text":6121},{"id":6165,"depth":489,"text":6166},{"id":6237,"depth":489,"text":6717},"Step 10: Merge And Sync main",{"id":6293,"depth":489,"text":6719},"Step 11: Create Local .env",{"id":6369,"depth":489,"text":6370},{"id":6423,"depth":489,"text":6722},"Step 13: Enable pdo_mysql If Needed",{"id":433,"depth":489,"text":436},{"id":6568,"depth":489,"text":6569},{"id":1715,"depth":489,"text":1718},{"id":1806,"depth":489,"text":1807},{"id":462,"depth":489,"text":465},"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":5676,"description":6728},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[3938,105,2173],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":6742,"title":6743,"audience":6,"body":6744,"contentType":505,"course":506,"description":7454,"estimateBasis":7455,"estimatedDiscussionMinutes":3928,"estimatedLiveMinutes":4871,"estimatedTotalMinutes":1946,"extension":512,"meta":7456,"module":514,"navigation":515,"order":3929,"path":7457,"promptAssist":518,"seo":7458,"status":520,"stem":7459,"tags":7460,"videoDuration":7462,"videoId":7463,"videoLink":7464,"videoTitle":7465,"week":514,"__hash__":7466},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":6745,"toc":7433},[6746,6780,6828,6850,6904,6969,7027,7077,7142,7183,7275,7315,7342,7400],[11,6747,6748,6750,6752],{"id":3951,"level":14},[16,6749,3954],{"id":3951},[37,6751,3957],{},[21,6753,6754,6763,6768,6772,6777],{},[24,6755,6756,6757,2671,6760],{},"Understand the purpose and usage of ",[262,6758,6759],{},"qa",[262,6761,6762],{},"prod",[24,6764,6765,6766],{},"Create and push ",[262,6767,6759],{},[24,6769,6765,6770],{},[262,6771,6762],{},[24,6773,6774,6775],{},"Keep local work pointed at ",[262,6776,6759],{},[24,6778,6779],{},"Confirm GitHub has the expected branches",[11,6781,6783,6786,6821],{"id":6782,"level":14},"branch-roles",[16,6784,6785],{"id":6782},"Branch Roles",[21,6787,6788,6798,6808,6818],{},[24,6789,6790,6792,6793],{},[262,6791,2138],{},": starter baseline and shared source branch\n",[21,6794,6795],{},[24,6796,6797],{},"Most projects stick with this; we'll split ours into development lanes",[24,6799,6800,6802,6803],{},[262,6801,6759],{},": public testing and evidence branch\n",[21,6804,6805],{},[24,6806,6807],{},"Normal branch to return to before new course work",[24,6809,6810,6812,6813],{},[262,6811,6762],{},": stable grading and evaluation branch\n",[21,6814,6815],{},[24,6816,6817],{},"Protected from everyday local edits",[24,6819,6820],{},"Later deployment setup connects Render to these branches",[37,6822,6823,6824,4986,6826],{},"Course flow: feature or homework branch -> ",[262,6825,6759],{},[262,6827,6762],{},[11,6829,6830,6832,6835,6839],{"id":981,"level":14},[16,6831,984],{"id":981},[37,6833,6834],{},"Run inside the course repository:",[1227,6836],{"label":6837,"language":1229,"src":6838},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[21,6840,6841,6844,6847],{},[24,6842,6843],{},"Working tree should be clean",[24,6845,6846],{},"Starter baseline already pushed to GitHub",[24,6848,6849],{},"Stop if Git says files are modified or untracked",[11,6851,6853,6859],{"id":6852,"level":14},"step-1-sync-main",[16,6854,6856,6857],{"id":6855},"step-1-start-from-main","Step 1: Start From ",[262,6858,2138],{},[100,6860,6861,6869],{"gap":102,"left-width":103,"right-width":103},[105,6862,6863,6865],{"v-slot:left":107},[37,6864,1225],{},[1227,6866],{"label":6867,"language":1229,"src":6868},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[105,6870,6871,6873,6876],{"v-slot:right":107},[37,6872,3097],{},[1227,6874],{"label":2957,"language":4008,"src":6875},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[21,6877,6878,6885],{},[24,6879,6880,6882,6883],{},[262,6881,6278],{},": switch to ",[262,6884,2138],{},[24,6886,6887,6889,6890,6892,6893],{},[262,6888,6284],{},": get the latest ",[262,6891,2138],{}," from GitHub\n",[21,6894,6895,6899],{},[24,6896,6897,6145],{},[262,6898,4360],{},[24,6900,6901,6903],{},[262,6902,2138],{},": remote branch being pulled",[11,6905,6907,6913],{"id":6906,"level":14},"step-2-create-qa",[16,6908,6910,6911],{"id":6909},"step-2-create-and-push-qa","Step 2: Create And Push ",[262,6912,6759],{},[100,6914,6915,6923],{"gap":102,"left-width":103,"right-width":103},[105,6916,6917,6919],{"v-slot:left":107},[37,6918,1225],{},[1227,6920],{"label":6921,"language":1229,"src":6922},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[105,6924,6925,6927,6930],{"v-slot:right":107},[37,6926,3097],{},[1227,6928],{"label":2957,"language":4008,"src":6929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[21,6931,6932,6949],{},[24,6933,6934,6937,6938,6940,6941],{},[262,6935,6936],{},"git checkout -b qa",": create ",[262,6939,6759],{}," and switch to it\n",[21,6942,6943],{},[24,6944,6945,6948],{},[262,6946,6947],{},"-b",": creates a new branch of the following name",[24,6950,6951,6954,6955,6957,6958],{},[262,6952,6953],{},"git push -u origin qa",": send ",[262,6956,6759],{}," to GitHub\n",[21,6959,6960],{},[24,6961,6962,6964,6965,6968],{},[262,6963,6150],{},": remember ",[262,6966,6967],{},"origin\u002Fqa"," as the upstream branch",[11,6970,6972,6978],{"id":6971,"level":14},"step-3-create-prod",[16,6973,6975,6976],{"id":6974},"step-3-create-and-push-prod","Step 3: Create And Push ",[262,6977,6762],{},[100,6979,6980,6988],{"gap":102,"left-width":103,"right-width":103},[105,6981,6982,6984],{"v-slot:left":107},[37,6983,1225],{},[1227,6985],{"label":6986,"language":1229,"src":6987},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[105,6989,6990,6992,6995],{"v-slot:right":107},[37,6991,3097],{},[1227,6993],{"label":2957,"language":4008,"src":6994},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[21,6996,6997,7005,7010,7022],{},[24,6998,5021,6999,7001,7002,7004],{},[262,7000,6762],{}," from the current ",[262,7003,6759],{}," branch",[24,7006,7007],{},[262,7008,7009],{},"git checkout -b prod",[24,7011,7012,7013,6957,7015],{},"Push ",[262,7014,6762],{},[21,7016,7017],{},[24,7018,7019],{},[262,7020,7021],{},"git push origin prod",[24,7023,7024,7026],{},[262,7025,6762],{}," starts from the same clean baseline",[11,7028,7030,7035],{"id":7029,"level":14},"step-4-return-to-qa",[16,7031,7032,7033],{"id":7029},"Step 4: Return To ",[262,7034,6759],{},[100,7036,7037,7045],{"gap":102,"left-width":103,"right-width":103},[105,7038,7039,7041],{"v-slot:left":107},[37,7040,1225],{},[1227,7042],{"label":7043,"language":1229,"src":7044},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[105,7046,7047,7049,7052],{"v-slot:right":107},[37,7048,3097],{},[1227,7050],{"label":2957,"language":4008,"src":7051},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[21,7053,7054,7059,7064],{},[24,7055,7056,7058],{},[262,7057,6759],{}," should have the asterisk",[24,7060,7061,7063],{},[262,7062,6762],{}," should still exist on GitHub",[24,7065,7066,7067,7069],{},"Do not start normal course work from ",[262,7068,6762],{},[21,7070,7071],{},[24,7072,7073,7074,7076],{},"We'll remove local ",[262,7075,6762],{}," to avoid this issue",[11,7078,7080,7086],{"id":7079,"level":14},"step-5-delete-local-prod",[16,7081,7083,7084],{"id":7082},"step-5-remove-local-prod","Step 5: Remove Local ",[262,7085,6762],{},[100,7087,7088,7096],{"gap":102,"left-width":103,"right-width":103},[105,7089,7090,7092],{"v-slot:left":107},[37,7091,1225],{},[1227,7093],{"label":7094,"language":1229,"src":7095},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[105,7097,7098,7100,7103],{"v-slot:right":107},[37,7099,3097],{},[1227,7101],{"label":2957,"language":4008,"src":7102},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[21,7104,7105,7127],{},[24,7106,7107,7110,7111,7113],{},[262,7108,7109],{},"git branch -d prod",": delete local ",[262,7112,6762],{},[21,7114,7115,7121],{},[24,7116,7117,7120],{},[262,7118,7119],{},"-d",": delete only if Git considers it safe",[24,7122,7123,7126],{},[262,7124,7125],{},"-D",": can be used as a forced delete",[24,7128,7129,7132,7133],{},[262,7130,7131],{},"git branch -r",": list remote branches\n",[21,7134,7135],{},[24,7136,7137,7138,7141],{},"Confirms ",[262,7139,7140],{},"origin\u002Fprod"," still exists",[11,7143,7145,7148,7151,7154,7168,7171],{"id":7144,"level":14},"github-check",[16,7146,7147],{"id":7144},"GitHub Check",[37,7149,7150],{},"Open the branch dropdown on GitHub",[37,7152,7153],{},"You should see:",[21,7155,7156,7160,7164],{},[24,7157,7158],{},[262,7159,2138],{},[24,7161,7162],{},[262,7163,6759],{},[24,7165,7166],{},[262,7167,6762],{},[37,7169,7170],{},"Branch roles:",[21,7172,7173,7178],{},[24,7174,7175,7177],{},[262,7176,6759],{},": testing and evidence",[24,7179,7180,7182],{},[262,7181,6762],{},": stable grading target",[11,7184,7186,7190],{"id":7185,"level":14},"normal-workflow",[16,7187,7189],{"id":7188},"normal-workflow-after-setup","Normal Workflow After Setup",[159,7191,7192,7209,7217,7228,7233,7247,7250,7257,7269],{},[24,7193,7194,7195,7197],{},"Return to ",[262,7196,6759],{},[21,7198,7199,7204],{},[24,7200,7201],{},[262,7202,7203],{},"git checkout qa",[24,7205,7206],{},[262,7207,7208],{},"git pull origin qa",[24,7210,7211,7212],{},"Create a feature or homework branch\n",[21,7213,7214],{},[24,7215,7216],{},"Branch name matches the task",[24,7218,7219,7220],{},"Commit the work on that branch\n",[21,7221,7222],{},[24,7223,7224,7225,7227],{},"Check ",[262,7226,4199],{}," before each Git command",[24,7229,7230,7231],{},"Push the branch and open a pull request into ",[262,7232,6759],{},[24,7234,7235,7236,7238,7239],{},"Merge into ",[262,7237,6759],{}," after review\n",[21,7240,7241],{},[24,7242,7243,7244,7246],{},"QA deployment will update from ",[262,7245,6759],{}," after Render setup",[24,7248,7249],{},"Test the QA version",[24,7251,7252,7253,6512,7255],{},"Open a pull request from ",[262,7254,6759],{},[262,7256,6762],{},[24,7258,7235,7259,7261,7262],{},[262,7260,6762],{}," when stable\n",[21,7263,7264],{},[24,7265,7266,7267,7246],{},"Production deployment will use ",[262,7268,6762],{},[24,7270,7271,7272,7274],{},"Return locally to ",[262,7273,6759],{}," and pull before the next task",[11,7276,7277,7279],{"id":1715,"level":14},[16,7278,1718],{"id":1715},[21,7280,7281,7286,7291,7299,7307,7310],{},[24,7282,7283,7284],{},"Working directly on ",[262,7285,6762],{},[24,7287,7288,7289],{},"Forgetting to return to ",[262,7290,6759],{},[24,7292,7293,7294,7296,7297],{},"Pushing ",[262,7295,6759],{}," but not ",[262,7298,6762],{},[24,7300,7301,7302,7304,7305],{},"Deleting remote ",[262,7303,6762],{}," instead of local ",[262,7306,6762],{},[24,7308,7309],{},"Assuming GitHub has the branch without checking",[24,7311,7312,7313,4678],{},"Starting new work before ",[262,7314,4199],{},[11,7316,7317,7319,7322],{"id":433,"level":14},[16,7318,436],{"id":433},[37,7320,7321],{},"Answer before moving on:",[21,7323,7324,7327,7330,7333,7339],{},[24,7325,7326],{},"Which branch should QA deployment watch?",[24,7328,7329],{},"Which branch should production grading use?",[24,7331,7332],{},"Which branch should you return to before new work?",[24,7334,7335,7336,7338],{},"Why remove local ",[262,7337,6762],{}," after pushing it?",[24,7340,7341],{},"What future setup connects Render to these branches?",[11,7343,7344,7346],{"id":1795,"level":14},[16,7345,1799],{"id":1798},[100,7347,7348,7373],{"gap":102,"left-width":103,"right-width":103},[105,7349,7350,7352],{"v-slot:left":107},[361,7351,1807],{"id":1806},[21,7353,7354,7357,7360,7365,7370],{},[24,7355,7356],{},"Branch: named line of Git history",[24,7358,7359],{},"Upstream: remote branch Git remembers for push\u002Fpull",[24,7361,7362,7364],{},[262,7363,6759],{},": public testing branch",[24,7366,7367,7369],{},[262,7368,6762],{},": stable grading branch",[24,7371,7372],{},"Remote-only branch: exists on GitHub, not locally",[105,7374,7375,7377],{"v-slot:right":107},[361,7376,1838],{"id":1795},[21,7378,7379,7386,7393],{},[24,7380,4773,7381],{},[41,7382,7385],{"href":7383,"rel":7384},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[45],"About branches",[24,7387,4773,7388],{},[41,7389,7392],{"href":7390,"rel":7391},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[45],"About pull requests",[24,7394,4758,7395],{},[41,7396,7399],{"href":7397,"rel":7398},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[45],"Git Branching",[11,7401,7402,7404,7406],{"id":462,"level":14},[16,7403,465],{"id":462},[37,7405,1868],{},[21,7407,7408,7417,7421,7425,7430],{},[24,7409,7410,7411,965,7413,969,7415],{},"Explain ",[262,7412,2138],{},[262,7414,6759],{},[262,7416,6762],{},[24,7418,6765,7419],{},[262,7420,6759],{},[24,7422,6765,7423],{},[262,7424,6762],{},[24,7426,7427,7428],{},"Keep local work branched from ",[262,7429,6759],{},[24,7431,7432],{},"Verify remote branches on GitHub",{"title":107,"searchDepth":489,"depth":489,"links":7434},[7435,7436,7437,7438,7440,7442,7444,7446,7448,7449,7450,7451,7452,7453],{"id":3951,"depth":489,"text":3954},{"id":6782,"depth":489,"text":6785},{"id":981,"depth":489,"text":984},{"id":6855,"depth":489,"text":7439},"Step 1: Start From main",{"id":6909,"depth":489,"text":7441},"Step 2: Create And Push qa",{"id":6974,"depth":489,"text":7443},"Step 3: Create And Push prod",{"id":7029,"depth":489,"text":7445},"Step 4: Return To qa",{"id":7082,"depth":489,"text":7447},"Step 5: Remove Local prod",{"id":7144,"depth":489,"text":7147},{"id":7188,"depth":489,"text":7189},{"id":1715,"depth":489,"text":1718},{"id":433,"depth":489,"text":436},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":6743,"description":7454},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[2173,4876,6759,7461],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":7468,"title":7469,"audience":6,"body":7470,"contentType":505,"course":506,"description":8277,"estimateBasis":8278,"estimatedDiscussionMinutes":3928,"estimatedLiveMinutes":1946,"estimatedTotalMinutes":3929,"extension":512,"meta":8279,"module":514,"navigation":515,"order":8280,"path":8281,"promptAssist":518,"seo":8282,"status":520,"stem":8283,"tags":8284,"videoDuration":8287,"videoId":8288,"videoLink":8289,"videoTitle":8290,"week":514,"__hash__":8291},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7471,"toc":8256},[7472,7499,7522,7551,7619,7680,7715,7751,7788,7838,7884,7919,7965,8002,8030,8062,8109,8142,8210],[11,7473,7475,7478],{"id":7474,"level":14},"render-setup-title",[16,7476,7469],{"id":7477},"render-setup",[21,7479,7480,7483,7488,7493,7496],{},[24,7481,7482],{},"Connect GitHub repo to Render",[24,7484,7485,7486],{},"Create a QA service from ",[262,7487,6759],{},[24,7489,7490,7491],{},"Create a production service from ",[262,7492,6762],{},[24,7494,7495],{},"Add the course database connection string",[24,7497,7498],{},"Verify live URLs and deploy logs",[11,7500,7501,7503,7505],{"id":2855,"level":14},[16,7502,2858],{"id":2855},[37,7504,3957],{},[21,7506,7507,7510,7513,7516,7519],{},[24,7508,7509],{},"Explain what Render does in the course workflow",[24,7511,7512],{},"Create separate QA and production services",[24,7514,7515],{},"Connect each service to the correct branch",[24,7517,7518],{},"Read Render logs when a deploy fails",[24,7520,7521],{},"Identify which deployed URL to submit or test",[11,7523,7525,7528,7545],{"id":7524,"level":14},"what-render-does",[16,7526,7527],{"id":7524},"What Render Does",[21,7529,7530,7533,7536,7539,7542],{},[24,7531,7532],{},"Hosts your PHP app from GitHub",[24,7534,7535],{},"Watches a selected branch",[24,7537,7538],{},"Rebuilds when that branch changes",[24,7540,7541],{},"Stores secrets as environment variables",[24,7543,7544],{},"Gives each service a public URL",[37,7546,7547,7548],{},"Course loop: ",[262,7549,7550],{},"local work -> GitHub branch -> Render URL",[11,7552,7554,7556],{"id":7553,"level":14},"free-tier-and-before-start",[16,7555,984],{"id":981},[100,7557,7558,7587],{"gap":102,"left-width":103,"right-width":103},[105,7559,7560,7564],{"v-slot:left":107},[361,7561,7563],{"id":7562},"free-tier","Free Tier",[21,7565,7566,7576,7584],{},[24,7567,3023,7568,7571],{},[262,7569,7570],{},"Free",[21,7572,7573],{},[24,7574,7575],{},"Render may default to a paid plan",[24,7577,7578,7579],{},"Free services can sleep",[21,7580,7581],{},[24,7582,7583],{},"First visit after sleep may be slow",[24,7585,7586],{},"Avoid extra services unless instructed",[105,7588,7589,7593],{"v-slot:right":107},[361,7590,7592],{"id":7591},"repo-ready","Repo Ready",[21,7594,7595,7598,7603,7612],{},[24,7596,7597],{},"Starter files committed and pushed",[24,7599,7600,7602],{},[262,7601,5967],{}," in repo root",[24,7604,7605,965,7607,969,7609,7611],{},[262,7606,1167],{},[262,7608,5875],{},[262,7610,5878],{}," present",[24,7613,7614,2671,7616,7618],{},[262,7615,6759],{},[262,7617,6762],{}," branches exist on GitHub",[11,7620,7622,7625],{"id":7621,"level":14},"target-architecture",[16,7623,7624],{"id":7621},"Target Architecture",[100,7626,7627,7655],{"gap":102,"left-width":103,"right-width":103},[105,7628,7629,7633],{"v-slot:left":107},[361,7630,7632],{"id":7631},"qa-service","QA Service",[21,7634,7635,7641,7646,7649],{},[24,7636,7637,7638],{},"Name: ",[262,7639,7640],{},"\u003Cucid>-it202-\u003Csection>-qa",[24,7642,7643,7644],{},"Watches ",[262,7645,6759],{},[24,7647,7648],{},"Used for testing and evidence",[24,7650,7651,7652],{},"URL ends with ",[262,7653,7654],{},"-qa.onrender.com",[105,7656,7657,7661],{"v-slot:right":107},[361,7658,7660],{"id":7659},"production-service","Production Service",[21,7662,7663,7668,7672,7675],{},[24,7664,7637,7665],{},[262,7666,7667],{},"\u003Cucid>-it202-\u003Csection>-prod",[24,7669,7643,7670],{},[262,7671,6762],{},[24,7673,7674],{},"Stable version after QA checks",[24,7676,7651,7677],{},[262,7678,7679],{},"-prod.onrender.com",[11,7681,7683,7687],{"id":7682,"level":14},"step-1-sign-up",[16,7684,7686],{"id":7685},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[100,7688,7689,7707],{"gap":102,"left-width":2558,"right-width":2557},[105,7690,7691],{"v-slot:left":107},[21,7692,7693,7698,7701,7704],{},[24,7694,2027,7695],{},[262,7696,7697],{},"render.com",[24,7699,7700],{},"Choose GitHub sign-in",[24,7702,7703],{},"Authorize Render when prompted",[24,7705,7706],{},"Land on the Render dashboard",[105,7708,7709],{"v-slot:right":107},[37,7710,7711],{},[140,7712],{"alt":7713,"src":7714,"variant":144},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,7716,7718,7721],{"id":7717,"level":14},"step-2-new-web-service",[16,7719,7720],{"id":7717},"Step 2: New Web Service",[100,7722,7723,7743],{"gap":102,"left-width":2558,"right-width":2557},[105,7724,7725],{"v-slot:left":107},[21,7726,7727,7732,7737,7740],{},[24,7728,166,7729],{},[262,7730,7731],{},"New +",[24,7733,3023,7734],{},[262,7735,7736],{},"Web Service",[24,7738,7739],{},"Do not choose a database service here",[24,7741,7742],{},"This creates the hosted PHP app",[105,7744,7745],{"v-slot:right":107},[37,7746,7747],{},[140,7748],{"alt":7749,"src":7750,"variant":144},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,7752,7754,7758],{"id":7753,"level":14},"step-3-connect-repo",[16,7755,7757],{"id":7756},"step-3-connect-repository","Step 3: Connect Repository",[100,7759,7760,7780],{"gap":102,"left-width":2053,"right-width":2598},[105,7761,7762],{"v-slot:left":107},[21,7763,7764,7767,7770,7777],{},[24,7765,7766],{},"Select your student course repository",[24,7768,7769],{},"Authorize repository access if Render asks",[24,7771,7772,7773,7776],{},"Ensure it's the proper repository (format: ",[262,7774,7775],{},"ucid-course-section-semYear",")",[24,7778,7779],{},"Continue to service settings",[105,7781,7782],{"v-slot:right":107},[37,7783,7784],{},[140,7785],{"alt":7786,"src":7787,"variant":144},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,7789,7791,7795],{"id":7790,"level":14},"step-4-configure-qa",[16,7792,7794],{"id":7793},"step-4-configure-qa-service","Step 4: Configure QA Service",[100,7796,7797,7830],{"gap":102,"left-width":2558,"right-width":2557},[105,7798,7799,7802],{"v-slot:left":107},[37,7800,7801],{},"Use these settings:",[21,7803,7804,7808,7813,7819,7824,7827],{},[24,7805,7637,7806],{},[262,7807,7640],{},[24,7809,7810,7811],{},"Branch: ",[262,7812,6759],{},[24,7814,7815,7816],{},"Runtime: ",[262,7817,7818],{},"Docker",[24,7820,7821,7822],{},"Instance type: ",[262,7823,7570],{},[24,7825,7826],{},"Root directory: blank",[24,7828,7829],{},"Build\u002Fstart commands: blank",[105,7831,7832],{"v-slot:right":107},[37,7833,7834],{},[140,7835],{"alt":7836,"src":7837,"variant":144},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,7839,7841,7845],{"id":7840,"level":14},"step-5-env-vars",[16,7842,7844],{"id":7843},"step-5-add-environment-variables","Step 5: Add Environment Variables",[100,7846,7847,7876],{"gap":102,"left-width":3008,"right-width":5200},[105,7848,7849],{"v-slot:left":107},[21,7850,7851,7864,7870,7873],{},[24,7852,7853,7854,7856],{},"Add ",[262,7855,6318],{},[21,7857,7858],{},[24,7859,7860,7861],{},"Get it from ",[41,7862,6323],{"href":5168,"rel":7863},[45],[24,7865,7866,7867,7869],{},"Do not use \"add from ",[262,7868,6299],{},"\"",[24,7871,7872],{},"Add later API keys only when a later lesson requires them",[24,7874,7875],{},"Repeat required env vars on both QA and production",[105,7877,7878],{"v-slot:right":107},[37,7879,7880],{},[140,7881],{"alt":7882,"src":7883,"variant":144},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,7885,7887,7890],{"id":7886,"level":14},"step-6-deploy-qa",[16,7888,7889],{"id":7886},"Step 6: Deploy QA",[100,7891,7892,7911],{"gap":102,"left-width":2053,"right-width":2598},[105,7893,7894],{"v-slot:left":107},[21,7895,7896,7899,7902,7905,7908],{},[24,7897,7898],{},"Create the QA service",[24,7900,7901],{},"Watch the first deploy log",[24,7903,7904],{},"Wait for a success state",[24,7906,7907],{},"Open the QA URL",[24,7909,7910],{},"Confirm the starter page loads",[105,7912,7913],{"v-slot:right":107},[37,7914,7915],{},[140,7916],{"alt":7917,"src":7918,"variant":144},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,7920,7922,7926],{"id":7921,"level":14},"step-7-create-prod",[16,7923,7925],{"id":7924},"step-7-create-production-service","Step 7: Create Production Service",[100,7927,7928,7957],{"gap":102,"left-width":2558,"right-width":2557},[105,7929,7930,7933],{"v-slot:left":107},[37,7931,7932],{},"Create a second web service:",[21,7934,7935,7938,7942,7946,7950,7954],{},[24,7936,7937],{},"Same repository",[24,7939,7637,7940],{},[262,7941,7667],{},[24,7943,7810,7944],{},[262,7945,6762],{},[24,7947,7815,7948],{},[262,7949,7818],{},[24,7951,7821,7952],{},[262,7953,7570],{},[24,7955,7956],{},"Same required env vars",[105,7958,7959],{"v-slot:right":107},[37,7960,7961],{},[140,7962],{"alt":7963,"src":7964,"variant":144},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,7966,7967,7970],{"id":7185,"level":14},[16,7968,7969],{"id":7185},"Normal Workflow",[159,7971,7972,7975,7978,7983,7986,7989,7992,7999],{},[24,7973,7974],{},"Work locally on a feature or homework branch",[24,7976,7977],{},"Commit and push that branch to GitHub",[24,7979,7980,7981],{},"Open a pull request into ",[262,7982,6759],{},[24,7984,7985],{},"Merge after review",[24,7987,7988],{},"Render updates the QA URL",[24,7990,7991],{},"Test the QA URL",[24,7993,7252,7994,6512,7996,7998],{},[262,7995,6759],{},[262,7997,6762],{}," after evidence gathering",[24,8000,8001],{},"Render updates the production URL",[11,8003,8005,8008],{"id":8004,"level":14},"urls-and-cold-starts",[16,8006,8007],{"id":8004},"URLs And Cold Starts",[21,8009,8010,8013,8016,8019,8027],{},[24,8011,8012],{},"QA URL shows the test deployment",[24,8014,8015],{},"Production URL shows the stable deployment",[24,8017,8018],{},"Homework evidence usually starts with QA",[24,8020,8021,8022],{},"Free services may sleep after inactivity\n",[21,8023,8024],{},[24,8025,8026],{},"First visit after sleep may take extra time (2 - 5 minutes)",[24,8028,8029],{},"Do not submit before Render finishes deploying",[11,8031,8033,8036],{"id":8032,"level":14},"logs-and-status",[16,8034,8035],{"id":8032},"Logs And Status",[100,8037,8038,8054],{"gap":102,"left-width":2053,"right-width":2598},[105,8039,8040],{"v-slot:left":107},[21,8041,8042,8045,8048,8051],{},[24,8043,8044],{},"Logs show build and startup output",[24,8046,8047],{},"Dashboard status shows deploy progress",[24,8049,8050],{},"Failed deploys usually show the first useful clue",[24,8052,8053],{},"Read the first clear error before changing settings",[105,8055,8056],{"v-slot:right":107},[37,8057,8058],{},[140,8059],{"alt":8060,"src":8061,"variant":144},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8063,8065,8068],{"id":8064,"level":14},"troubleshooting",[16,8066,8067],{"id":8064},"Troubleshooting",[21,8069,8070,8080,8088,8098],{},[24,8071,8072,8073],{},"Build fails\n",[21,8074,8075],{},[24,8076,7224,8077,8079],{},[262,8078,5967],{},", root directory, runtime, and instance type",[24,8081,8082,8083],{},"App deploys but page fails\n",[21,8084,8085],{},[24,8086,8087],{},"Check logs for PHP errors",[24,8089,8090,8091],{},"Database connection fails\n",[21,8092,8093],{},[24,8094,7224,8095,8097],{},[262,8096,6318],{}," spelling and copied value",[24,8099,8100,8101],{},"Wrong version appears\n",[21,8102,8103,8106],{},[24,8104,8105],{},"Confirm the service watches the expected branch",[24,8107,8108],{},"Clear browser cache or test in a private window",[11,8110,8111,8113],{"id":1715,"level":14},[16,8112,1718],{"id":1715},[21,8114,8115,8125,8128,8133,8136,8139],{},[24,8116,8117,8118,8120,8121,1544,8123],{},"Choosing ",[262,8119,2138],{}," instead of ",[262,8122,6759],{},[262,8124,6762],{},[24,8126,8127],{},"Creating one service for both environments",[24,8129,8130,8131],{},"Forgetting ",[262,8132,6318],{},[24,8134,8135],{},"Using a paid instance type by accident",[24,8137,8138],{},"Checking GitHub but not the Render URL",[24,8140,8141],{},"Changing code locally but forgetting to push and merge",[11,8143,8144,8146],{"id":1798,"level":14},[16,8145,1799],{"id":1798},[100,8147,8148,8176],{"gap":102,"left-width":103,"right-width":103},[105,8149,8150,8152,8158,8164,8170],{"v-slot:left":107},[361,8151,1807],{"id":1806},[37,8153,8154,8157],{},[122,8155,8156],{},"Service"," - one deployed app on Render",[37,8159,8160,8163],{},[122,8161,8162],{},"Watched branch"," - Git branch Render deploys from",[37,8165,8166,8169],{},[122,8167,8168],{},"Environment variable"," - setting stored outside code",[37,8171,8172,8175],{},[122,8173,8174],{},"Deploy log"," - output from Render's build\u002Fstart process",[105,8177,8178,8180],{"v-slot:right":107},[361,8179,1838],{"id":1795},[21,8181,8182,8189,8196,8203],{},[24,8183,8184],{},[41,8185,8188],{"href":8186,"rel":8187},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[45],"Render Docs: Web Services",[24,8190,8191],{},[41,8192,8195],{"href":8193,"rel":8194},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[45],"Render Docs: Deploys",[24,8197,8198],{},[41,8199,8202],{"href":8200,"rel":8201},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[45],"Render Docs: Environment Variables",[24,8204,8205],{},[41,8206,8209],{"href":8207,"rel":8208},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[45],"Render Docs: Free Instance Types",[11,8211,8212,8214,8217],{"id":462,"level":14},[16,8213,465],{"id":462},[37,8215,8216],{},"Before leaving this presentation, confirm you:",[21,8218,8219,8222,8225,8232,8235,8238],{},[24,8220,8221],{},"Created QA and production Render services",[24,8223,8224],{},"Matched each service to the correct branch",[24,8226,8227,8228,6319,8230],{},"Added ",[262,8229,6318],{},[262,8231,6323],{},[24,8233,8234],{},"Opened each deployed URL",[24,8236,8237],{},"Read logs instead of assuming it worked",[24,8239,8240,8241],{},"Understand the local -> GitHub -> Render loop\n",[21,8242,8243,8246,8251],{},[24,8244,8245],{},"Majority of your work will be done locally and tested locally",[24,8247,8248,8250],{},[262,8249,6759],{}," is just for gathering evidence for submissions",[24,8252,8253,8255],{},[262,8254,6762],{}," is what will be verified during grading",{"title":107,"searchDepth":489,"depth":489,"links":8257},[8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276],{"id":7477,"depth":489,"text":7469},{"id":2855,"depth":489,"text":2858},{"id":7524,"depth":489,"text":7527},{"id":981,"depth":489,"text":984},{"id":7621,"depth":489,"text":7624},{"id":7685,"depth":489,"text":7686},{"id":7717,"depth":489,"text":7720},{"id":7756,"depth":489,"text":7757},{"id":7793,"depth":489,"text":7794},{"id":7843,"depth":489,"text":7844},{"id":7886,"depth":489,"text":7889},{"id":7924,"depth":489,"text":7925},{"id":7185,"depth":489,"text":7969},{"id":8004,"depth":489,"text":8007},{"id":8032,"depth":489,"text":8035},{"id":8064,"depth":489,"text":8067},{"id":1715,"depth":489,"text":1718},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":7469,"description":8277},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8285,8286,6759,7461],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8293,"title":8294,"audience":6,"body":8295,"contentType":505,"course":506,"description":10969,"estimateBasis":10970,"estimatedDiscussionMinutes":10971,"estimatedLiveMinutes":10972,"estimatedTotalMinutes":10973,"extension":512,"meta":10974,"module":514,"navigation":515,"order":4869,"path":10975,"promptAssist":518,"seo":10976,"status":520,"stem":10977,"tags":10978,"videoDuration":10983,"videoId":10984,"videoLink":10985,"videoTitle":10986,"week":514,"__hash__":10987},"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":8296,"toc":10901},[8297,8326,8371,8407,8476,8508,8535,8567,8593,8622,8651,8678,8709,8737,8773,8838,8873,8919,8962,9006,9053,9116,9152,9187,9224,9257,9294,9327,9357,9387,9417,9447,9477,9511,9543,9575,9607,9656,9658,9701,9727,9768,9820,9899,9950,9981,10011,10041,10091,10116,10166,10214,10272,10330,10371,10401,10435,10469,10503,10554,10606,10625,10653,10701,10773,10873],[11,8298,8300,8303],{"id":8299,"level":14},"virtualbox-title",[16,8301,8294],{"id":8302},"local-ubuntu-web-server-with-virtualbox",[21,8304,8305,8308,8311,8314,8317,8323],{},[24,8306,8307],{},"Primary course path for the local Ubuntu VM",[24,8309,8310],{},"Create an Ubuntu Server VM in VirtualBox",[24,8312,8313],{},"Connect from your host terminal with SSH",[24,8315,8316],{},"Share the course repo into Ubuntu",[24,8318,8319,8320,8322],{},"Serve ",[262,8321,1167],{}," through Apache and PHP",[24,8324,8325],{},"Create a local MySQL database for testing",[11,8327,8329,8332,8335,8346,8349],{"id":8328,"level":14},"main-goal",[16,8330,8331],{"id":8328},"Main Goal",[37,8333,8334],{},"Your host computer and Ubuntu VM have different jobs:",[21,8336,8337,8340,8343],{},[24,8338,8339],{},"Host computer: edit files with VS Code and open the browser",[24,8341,8342],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[24,8344,8345],{},"Shared folder: lets both use the same course repo files",[37,8347,8348],{},"Target result:",[21,8350,8351,8357,8362,8365,8368],{},[24,8352,8353,8354],{},"Host browser opens ",[262,8355,8356],{},"http:\u002F\u002Flocalhost:3000",[24,8358,8359,8360],{},"Apache serves the repo's ",[262,8361,1167],{},[24,8363,8364],{},"PHP executes inside Ubuntu",[24,8366,8367],{},"Local MySQL has a database and user named after your UCID",[24,8369,8370],{},"Edits made on the host appear after browser refresh",[11,8372,8374,8377,8380,8399,8402],{"id":8373,"level":14},"virtualbox-caveat",[16,8375,8376],{"id":8373},"VirtualBox Caveat",[37,8378,8379],{},"VirtualBox is the primary local VM path for this course:",[21,8381,8382,8385,8388,8396],{},[24,8383,8384],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[24,8386,8387],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[24,8389,8390,8391],{},"Windows on Arm support is experimental in VirtualBox\n",[21,8392,8393],{},[24,8394,8395],{},"Avoid unless your instructor confirms it for your machine",[24,8397,8398],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[37,8400,8401],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[2270,8403,8404],{"type":3545},[37,8405,8406],{},"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,8408,8409,8411],{"id":981,"level":14},[16,8410,984],{"id":981},[21,8412,8413,8431,8449,8452,8455,8458,8473],{},[24,8414,8415,8416],{},"VirtualBox downloaded\n",[21,8417,8418,8425,8428],{},[24,8419,8420],{},[41,8421,8424],{"href":8422,"rel":8423},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[45],"VirtualBox downloads",[24,8426,8427],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[24,8429,8430],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[24,8432,8433,8434],{},"Ubuntu Server ISO downloaded\n",[21,8435,8436,8443,8446],{},[24,8437,8438],{},[41,8439,8442],{"href":8440,"rel":8441},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[45],"Ubuntu Server installer",[24,8444,8445],{},"Apple Silicon Mac: use the ARM64 server ISO",[24,8447,8448],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[24,8450,8451],{},"Internet Applications course repo cloned on host computer",[24,8453,8454],{},"Git\u002FGitHub setup already working",[24,8456,8457],{},"Administrator access on your computer",[24,8459,8460,8461,8464,8465],{},"At least ",[262,8462,8463],{},"10 GB"," free disk space for the VM\n",[21,8466,8467],{},[24,8468,8469,8472],{},[262,8470,8471],{},"20-25 GB"," is safer if your computer has room",[24,8474,8475],{},"Stable internet for package installs",[11,8477,8479,8482],{"id":8478,"level":14},"setup-parts",[16,8480,8481],{"id":8478},"Setup Parts",[21,8483,8484,8487,8490,8493,8499,8502,8505],{},[24,8485,8486],{},"VM: Ubuntu Server running inside VirtualBox",[24,8488,8489],{},"NAT adapter: gives the VM internet access",[24,8491,8492],{},"Port forwarding: lets the host reach SSH and Apache",[24,8494,8495,8496],{},"SSH: lets the host terminal control Ubuntu through ",[262,8497,8498],{},"localhost",[24,8500,8501],{},"Shared folder: exposes the host repo inside Ubuntu",[24,8503,8504],{},"Apache\u002FPHP: serves and executes the web app",[24,8506,8507],{},"MySQL: local database server for local testing",[11,8509,8511,8515],{"id":8510,"level":14},"install-virtualbox-windows",[16,8512,8514],{"id":8513},"install-virtualbox-on-windows","Install VirtualBox On Windows",[21,8516,8517,8520,8523,8526,8529,8532],{},[24,8518,8519],{},"Download VirtualBox for Windows hosts",[24,8521,8522],{},"Run the installer as an administrator if prompted",[24,8524,8525],{},"Keep the default install path and features",[24,8527,8528],{},"Accept the network reset warning",[24,8530,8531],{},"Open VirtualBox after installation",[24,8533,8534],{},"See the slides below for the Windows installer screens",[11,8536,8538,8541],{"id":8537,"level":95},"windows-installer-start",[16,8539,8540],{"id":8537},"Windows Installer: Start",[100,8542,8543,8551],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8544,8545],{"v-slot:left":107},[37,8546,8547],{},[140,8548],{"alt":8549,"src":8550,"variant":144},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[105,8552,8553],{"v-slot:right":107},[21,8554,8555,8561,8564],{},[24,8556,8557,8558],{},"Launch the downloaded ",[262,8559,8560],{},".exe",[24,8562,8563],{},"Approve the Windows security prompt if shown",[24,8565,8566],{},"Start the setup wizard",[11,8568,8570,8573],{"id":8569,"level":95},"windows-installer-features",[16,8571,8572],{"id":8569},"Windows Installer: Features",[100,8574,8575,8583],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8576,8577],{"v-slot:left":107},[37,8578,8579],{},[140,8580],{"alt":8581,"src":8582,"variant":144},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[105,8584,8585],{"v-slot:right":107},[21,8586,8587,8590],{},[24,8588,8589],{},"Keep the default install location",[24,8591,8592],{},"Keep the default features selected",[11,8594,8596,8599],{"id":8595,"level":95},"windows-installer-network-warning",[16,8597,8598],{"id":8595},"Windows Installer: Network Warning",[100,8600,8601,8609],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8602,8603],{"v-slot:left":107},[37,8604,8605],{},[140,8606],{"alt":8607,"src":8608,"variant":144},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[105,8610,8611],{"v-slot:right":107},[21,8612,8613,8616,8619],{},[24,8614,8615],{},"VirtualBox may reset network adapters briefly",[24,8617,8618],{},"This is expected during install",[24,8620,8621],{},"Save web work before continuing if needed",[11,8623,8625,8628],{"id":8624,"level":95},"windows-installer-ready",[16,8626,8627],{"id":8624},"Windows Installer: Ready",[100,8629,8630,8638],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8631,8632],{"v-slot:left":107},[37,8633,8634],{},[140,8635],{"alt":8636,"src":8637,"variant":144},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[105,8639,8640],{"v-slot:right":107},[21,8641,8642,8645,8648],{},[24,8643,8644],{},"Start the installation",[24,8646,8647],{},"Keep the default choices",[24,8649,8650],{},"Wait for the installer to request permissions if needed",[11,8652,8654,8658],{"id":8653,"level":95},"windows-installer-progress",[16,8655,8657],{"id":8656},"windows-installer-start-options","Windows Installer: Start Options",[100,8659,8660,8668],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8661,8662],{"v-slot:left":107},[37,8663,8664],{},[140,8665],{"alt":8666,"src":8667,"variant":144},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[105,8669,8670],{"v-slot:right":107},[21,8671,8672,8675],{},[24,8673,8674],{},"No need to create a Start Menu item or desktop shortcut unless desired",[24,8676,8677],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,8679,8681,8684],{"id":8680,"level":95},"windows-installer-permission",[16,8682,8683],{"id":8680},"Windows Installer: Permission",[100,8685,8686,8694],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8687,8688],{"v-slot:left":107},[37,8689,8690],{},[140,8691],{"alt":8692,"src":8693,"variant":144},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[105,8695,8696],{"v-slot:right":107},[21,8697,8698,8701],{},[24,8699,8700],{},"Proceed with install",[24,8702,8703,8704],{},"Approve VirtualBox driver prompts\n",[21,8705,8706],{},[24,8707,8708],{},"These let VirtualBox create virtual hardware",[11,8710,8712,8715],{"id":8711,"level":95},"windows-installer-complete",[16,8713,8714],{"id":8711},"Windows Installer: Complete",[100,8716,8717,8725],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8718,8719],{"v-slot:left":107},[37,8720,8721],{},[140,8722],{"alt":8723,"src":8724,"variant":144},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[105,8726,8727],{"v-slot:right":107},[21,8728,8729,8731,8734],{},[24,8730,2418],{},[24,8732,8733],{},"Open VirtualBox",[24,8735,8736],{},"Continue to VM creation",[11,8738,8740,8744],{"id":8739,"level":14},"install-virtualbox-macos",[16,8741,8743],{"id":8742},"install-virtualbox-on-macos","Install VirtualBox On macOS",[100,8745,8746,8765],{"gap":102,"left-width":3008,"right-width":5200,"stack":2054},[105,8747,8748],{"v-slot:left":107},[21,8749,8750,8753,8756,8759,8762],{},[24,8751,8752],{},"Install the VirtualBox host package for your Mac CPU type",[24,8754,8755],{},"Intel Mac: standard macOS host installer",[24,8757,8758],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[24,8760,8761],{},"Approve macOS security prompts if needed",[24,8763,8764],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[105,8766,8767],{"v-slot:right":107},[37,8768,8769],{},[140,8770],{"alt":8771,"src":8772,"variant":144},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,8774,8776,8780,8783],{"id":8775,"level":14},"step-1-create-vm",[16,8777,8779],{"id":8778},"step-1-create-the-vm","Step 1: Create The VM",[37,8781,8782],{},"Create a lightweight Ubuntu Server VM:",[21,8784,8785,8788,8796,8811,8823,8829,8832,8835],{},[24,8786,8787],{},"Type: Linux",[24,8789,8790,8791],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[21,8792,8793],{},[24,8794,8795],{},"Match the version to the ISO you downloaded",[24,8797,8798,8799,8802,8803],{},"Memory: ",[262,8800,8801],{},"1 GB"," course target\n",[21,8804,8805],{},[24,8806,1493,8807,8810],{},[262,8808,8809],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[24,8812,8813,8814,8816,8817],{},"Disk: ",[262,8815,8463],{}," course minimum\n",[21,8818,8819],{},[24,8820,8821,8472],{},[262,8822,8471],{},[24,8824,8825,8826,8828],{},"CPU: ",[262,8827,514],{}," core is enough for this course VM",[24,8830,8831],{},"Enable OpenSSH during install if prompted",[24,8833,8834],{},"Username: use your UCID",[24,8836,8837],{},"See the slides below for VM settings and Ubuntu install screens",[11,8839,8841,8844],{"id":8840,"level":95},"vm-setup-name-and-iso",[16,8842,8843],{"id":8840},"VM Setup: Name And ISO",[100,8845,8846,8854],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8847,8848],{"v-slot:left":107},[37,8849,8850],{},[140,8851],{"alt":8852,"src":8853,"variant":144},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[105,8855,8856],{"v-slot:right":107},[21,8857,8858,8861,8867,8870],{},[24,8859,8860],{},"Start a new virtual machine",[24,8862,8863,8864],{},"Name it clearly, such as ",[262,8865,8866],{},"it202-vm",[24,8868,8869],{},"Choose the Ubuntu Server ISO file next",[24,8871,8872],{},"OS fields may look wrong until the ISO is selected",[11,8874,8876,8879],{"id":8875,"level":95},"vm-setup-confirm-ubuntu-iso",[16,8877,8878],{"id":8875},"VM Setup: Confirm Ubuntu ISO",[100,8880,8881,8889],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8882,8883],{"v-slot:left":107},[37,8884,8885],{},[140,8886],{"alt":8887,"src":8888,"variant":144},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[105,8890,8891],{"v-slot:right":107},[21,8892,8893,8899,8905,8908],{},[24,8894,8895,8896],{},"Confirm OS is ",[262,8897,8898],{},"Linux",[24,8900,8901,8902],{},"Confirm distribution is ",[262,8903,8904],{},"Ubuntu",[24,8906,8907],{},"Confirm version matches your ISO",[24,8909,2072,8910,8913,8914],{},[262,8911,8912],{},"Unattended Installation"," off\n",[21,8915,8916],{},[24,8917,8918],{},"The Ubuntu installer screens are easier to teach manually",[11,8920,8922,8925],{"id":8921,"level":95},"vm-setup-memory-and-cpu",[16,8923,8924],{"id":8921},"VM Setup: Memory And CPU",[100,8926,8927,8935],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8928,8929],{"v-slot:left":107},[37,8930,8931],{},[140,8932],{"alt":8933,"src":8934,"variant":144},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[105,8936,8937],{"v-slot:right":107},[21,8938,8939,8952,8956,8959],{},[24,8940,8798,8941,8802,8944],{},[262,8942,8943],{},"1024 MB",[21,8945,8946,8949],{},[24,8947,8948],{},"The goal is to match free-tier cloud services",[24,8950,8951],{},"Demonstrates that small apps can run with limited resources",[24,8953,8825,8954],{},[262,8955,514],{},[24,8957,8958],{},"Keep EFI off unless your machine requires it",[24,8960,8961],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,8963,8965,8968],{"id":8964,"level":95},"vm-setup-virtual-disk",[16,8966,8967],{"id":8964},"VM Setup: Virtual Disk",[100,8969,8970,8978],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,8971,8972],{"v-slot:left":107},[37,8973,8974],{},[140,8975],{"alt":8976,"src":8977,"variant":144},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[105,8979,8980],{"v-slot:right":107},[21,8981,8982,8988,8991,9003],{},[24,8983,8984,8985],{},"Disk type: ",[262,8986,8987],{},"VDI",[24,8989,8990],{},"Storage: dynamically allocated",[24,8992,8993,8994,8996],{},"Minimum: ",[262,8995,8463],{},[21,8997,8998],{},[24,8999,9000,9002],{},[262,9001,8471],{}," is safer if you have room",[24,9004,9005],{},"Dynamic disk uses space as needed, not all at once",[11,9007,9009,9012],{"id":9008,"level":95},"vm-setup-start-with-gui",[16,9010,9011],{"id":9008},"VM Setup: Start With GUI",[100,9013,9014,9022],{"gap":102,"left-width":2052,"right-width":2053,"stack":2054},[105,9015,9016],{"v-slot:left":107},[37,9017,9018],{},[140,9019],{"alt":9020,"src":9021,"variant":144},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[105,9023,9024],{"v-slot:right":107},[21,9025,9026,9029,9039,9042],{},[24,9027,9028],{},"Select the newly created VM",[24,9030,166,9031,9034],{},[262,9032,9033],{},"Start",[21,9035,9036],{},[24,9037,9038],{},"Choose the normal GUI start for the first boot",[24,9040,9041],{},"Complete the Ubuntu installer in the VM window",[24,9043,9044,9045],{},"After install and SSH setup, future starts can be headless\n",[21,9046,9047],{},[24,9048,9049,9050,9052],{},"You will connect with ",[262,9051,3937],{}," when you need the VM",[11,9054,9056,9060,9063],{"id":9055,"level":14},"ubuntu-installer",[16,9057,9059],{"id":9058},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[37,9061,9062],{},"Use the Ubuntu Server installer after the VM starts:",[21,9064,9065,9068,9071,9074,9077,9080,9113],{},[24,9066,9067],{},"Choose the default course options unless noted",[24,9069,9070],{},"Continue without updating the installer if instructed",[24,9072,9073],{},"Use your UCID for the Ubuntu username",[24,9075,9076],{},"Install OpenSSH server during setup",[24,9078,9079],{},"Skip optional server snaps",[24,9081,9082,9083],{},"Keyboard navigation:\n",[21,9084,9085,9092,9102,9108],{},[24,9086,9087,9091],{},[9088,9089,9090],"kbd",{},"Tab"," moves between fields and buttons",[24,9093,9094,9097,9098,9101],{},[9088,9095,9096],{},"Up"," \u002F ",[9088,9099,9100],{},"Down"," moves through lists",[24,9103,9104,9107],{},[9088,9105,9106],{},"Space"," toggles checkboxes",[24,9109,9110,9112],{},[9088,9111,1577],{}," confirms the selected option",[24,9114,9115],{},"See the slides below for the installer screens",[11,9117,9119,9123],{"id":9118,"level":95},"ubuntu-installer-boot-menu",[16,9120,9122],{"id":9121},"step-21-boot-menu","Step 2.1: Boot Menu",[100,9124,9127,9136],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},"1.75fr","0.65fr",[105,9128,9129],{"v-slot:left":107},[37,9130,9131],{},[140,9132],{"alt":9133,"src":9134,"variant":9135},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[105,9137,9138],{"v-slot:right":107},[21,9139,9140,9145,9149],{},[24,9141,3023,9142],{},[262,9143,9144],{},"Try or Install Ubuntu Server",[24,9146,1609,9147],{},[9088,9148,1577],{},[24,9150,9151],{},"This starts the Ubuntu Server installer",[11,9153,9155,9159],{"id":9154,"level":95},"ubuntu-installer-language",[16,9156,9158],{"id":9157},"step-22-language","Step 2.2: Language",[100,9160,9161,9169],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9162,9163],{"v-slot:left":107},[37,9164,9165],{},[140,9166],{"alt":9167,"src":9168,"variant":9135},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[105,9170,9171],{"v-slot:right":107},[21,9172,9173,9176,9182],{},[24,9174,9175],{},"Choose your preferred language",[24,9177,9178,9181],{},[262,9179,9180],{},"English"," is the expected course screenshot path",[24,9183,1609,9184,9186],{},[9088,9185,1577],{}," to continue",[11,9188,9190,9194],{"id":9189,"level":95},"ubuntu-installer-update",[16,9191,9193],{"id":9192},"step-23-update-prompt","Step 2.3: Update Prompt",[100,9195,9196,9204],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9197,9198],{"v-slot:left":107},[37,9199,9200],{},[140,9201],{"alt":9202,"src":9203,"variant":9135},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[105,9205,9206],{"v-slot:right":107},[21,9207,9208,9218,9221],{},[24,9209,3023,9210,9213],{},[262,9211,9212],{},"Continue without updating",[21,9214,9215],{},[24,9216,9217],{},"If I forget to update the image, it's the second option",[24,9219,9220],{},"Keeps the install path consistent",[24,9222,9223],{},"Package updates happen after Ubuntu is installed",[11,9225,9227,9231],{"id":9226,"level":95},"ubuntu-installer-keyboard",[16,9228,9230],{"id":9229},"step-24-keyboard","Step 2.4: Keyboard",[100,9232,9233,9241],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9234,9235],{"v-slot:left":107},[37,9236,9237],{},[140,9238],{"alt":9239,"src":9240,"variant":9135},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[105,9242,9243],{"v-slot:right":107},[21,9244,9245,9248,9254],{},[24,9246,9247],{},"Keep the detected keyboard layout if it matches",[24,9249,9250,9251],{},"Common setting: ",[262,9252,9253],{},"English (US)",[24,9255,9256],{},"Use Identify keyboard only if typing is wrong",[11,9258,9260,9264],{"id":9259,"level":95},"ubuntu-installer-install-type",[16,9261,9263],{"id":9262},"step-25-install-type","Step 2.5: Install Type",[100,9265,9266,9274],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9267,9268],{"v-slot:left":107},[37,9269,9270],{},[140,9271],{"alt":9272,"src":9273,"variant":9135},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[105,9275,9276],{"v-slot:right":107},[21,9277,9278,9288,9291],{},[24,9279,9280,9281,9284,9285],{},"Select ",[262,9282,9283],{},"Ubuntu Server (minimized)","; don't choose full ",[262,9286,9287],{},"Ubuntu Server",[24,9289,9290],{},"Keep third-party drivers unchecked",[24,9292,9293],{},"Minimized keeps the VM lighter and aids future lessons",[11,9295,9297,9301],{"id":9296,"level":95},"ubuntu-installer-network",[16,9298,9300],{"id":9299},"step-26-network","Step 2.6: Network",[100,9302,9303,9311],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9304,9305],{"v-slot:left":107},[37,9306,9307],{},[140,9308],{"alt":9309,"src":9310,"variant":9135},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[105,9312,9313],{"v-slot:right":107},[21,9314,9315,9318,9324],{},[24,9316,9317],{},"DHCP address is expected",[24,9319,9320,9323],{},[262,9321,9322],{},"10.0.2.15"," is normal for VirtualBox NAT",[24,9325,9326],{},"Leave the network settings alone",[11,9328,9330,9334],{"id":9329,"level":95},"ubuntu-installer-proxy",[16,9331,9333],{"id":9332},"step-27-proxy","Step 2.7: Proxy",[100,9335,9336,9344],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9337,9338],{"v-slot:left":107},[37,9339,9340],{},[140,9341],{"alt":9342,"src":9343,"variant":9135},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[105,9345,9346],{"v-slot:right":107},[21,9347,9348,9351,9354],{},[24,9349,9350],{},"Leave proxy blank",[24,9352,9353],{},"Only fill this in if your network requires a proxy",[24,9355,9356],{},"Most student home networks do not need one",[11,9358,9360,9364],{"id":9359,"level":95},"ubuntu-installer-mirror",[16,9361,9363],{"id":9362},"step-28-mirror","Step 2.8: Mirror",[100,9365,9366,9374],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9367,9368],{"v-slot:left":107},[37,9369,9370],{},[140,9371],{"alt":9372,"src":9373,"variant":9135},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[105,9375,9376],{"v-slot:right":107},[21,9377,9378,9381,9384],{},[24,9379,9380],{},"Keep the default Ubuntu archive mirror",[24,9382,9383],{},"Wait for the mirror check to finish",[24,9385,9386],{},"Continue when the installer allows it",[11,9388,9390,9394],{"id":9389,"level":95},"ubuntu-installer-storage-guided",[16,9391,9393],{"id":9392},"step-29-guided-storage","Step 2.9: Guided Storage",[100,9395,9396,9404],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9397,9398],{"v-slot:left":107},[37,9399,9400],{},[140,9401],{"alt":9402,"src":9403,"variant":9135},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[105,9405,9406],{"v-slot:right":107},[21,9407,9408,9411,9414],{},[24,9409,9410],{},"Use the entire virtual disk",[24,9412,9413],{},"LVM is optional, not needed for this course VM",[24,9415,9416],{},"Leave encryption off",[11,9418,9420,9424],{"id":9419,"level":95},"ubuntu-installer-storage-summary",[16,9421,9423],{"id":9422},"step-210-storage-summary","Step 2.10: Storage Summary",[100,9425,9426,9434],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9427,9428],{"v-slot:left":107},[37,9429,9430],{},[140,9431],{"alt":9432,"src":9433,"variant":9135},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[105,9435,9436],{"v-slot:right":107},[21,9437,9438,9441,9444],{},[24,9439,9440],{},"Confirm the virtual disk is selected",[24,9442,9443],{},"This only affects the VM disk file",[24,9445,9446],{},"Continue when the layout looks correct",[11,9448,9450,9454],{"id":9449,"level":95},"ubuntu-installer-confirm-storage",[16,9451,9453],{"id":9452},"step-211-confirm-storage","Step 2.11: Confirm Storage",[100,9455,9456,9464],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9457,9458],{"v-slot:left":107},[37,9459,9460],{},[140,9461],{"alt":9462,"src":9463,"variant":9135},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[105,9465,9466],{"v-slot:right":107},[21,9467,9468,9471,9474],{},[24,9469,9470],{},"Confirm the virtual disk format",[24,9472,9473],{},"This does not erase your host computer files",[24,9475,9476],{},"It formats the VM's virtual disk",[11,9478,9480,9484],{"id":9479,"level":95},"ubuntu-installer-profile",[16,9481,9483],{"id":9482},"step-212-profile","Step 2.12: Profile",[100,9485,9486,9494],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9487,9488],{"v-slot:left":107},[37,9489,9490],{},[140,9491],{"alt":9492,"src":9493,"variant":9135},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[105,9495,9496],{"v-slot:right":107},[21,9497,9498,9501,9506,9508],{},[24,9499,9500],{},"Your name: your UCID or name is fine",[24,9502,9503,9504],{},"Server name: ",[262,9505,8866],{},[24,9507,5154],{},[24,9509,9510],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9512,9514,9518],{"id":9513,"level":95},"ubuntu-installer-pro",[16,9515,9517],{"id":9516},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[100,9519,9520,9528],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9521,9522],{"v-slot:left":107},[37,9523,9524],{},[140,9525],{"alt":9526,"src":9527,"variant":9135},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[105,9529,9530],{"v-slot:right":107},[21,9531,9532,9537,9540],{},[24,9533,3023,9534],{},[262,9535,9536],{},"Skip for now",[24,9538,9539],{},"Ubuntu Pro is not needed for the course VM",[24,9541,9542],{},"You can continue without an Ubuntu account",[11,9544,9546,9550],{"id":9545,"level":95},"ubuntu-installer-ssh",[16,9547,9549],{"id":9548},"step-214-ssh","Step 2.14: SSH",[100,9551,9552,9560],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9553,9554],{"v-slot:left":107},[37,9555,9556],{},[140,9557],{"alt":9558,"src":9559,"variant":9135},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[105,9561,9562],{"v-slot:right":107},[21,9563,9564,9569,9572],{},[24,9565,7224,9566],{},[262,9567,9568],{},"Install OpenSSH server",[24,9570,9571],{},"Password authentication is fine for this local VM",[24,9573,9574],{},"No need to import SSH keys for this course setup",[11,9576,9578,9582],{"id":9577,"level":95},"ubuntu-installer-snaps",[16,9579,9581],{"id":9580},"step-215-featured-snaps","Step 2.15: Featured Snaps",[100,9583,9584,9592],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9585,9586],{"v-slot:left":107},[37,9587,9588],{},[140,9589],{"alt":9590,"src":9591,"variant":9135},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[105,9593,9594],{"v-slot:right":107},[21,9595,9596,9599,9604],{},[24,9597,9598],{},"Leave all featured snaps unchecked",[24,9600,9601,9602],{},"Apache, PHP, and MySQL are installed later with ",[262,9603,6434],{},[24,9605,9606],{},"Continue without selecting extra packages",[11,9608,9610,9614],{"id":9609,"level":95},"ubuntu-installer-installing",[16,9611,9613],{"id":9612},"step-216-installing","Step 2.16: Installing",[100,9615,9616,9624],{"gap":512,"left-width":9125,"right-width":9126,"stack":2054},[105,9617,9618],{"v-slot:left":107},[37,9619,9620],{},[140,9621],{"alt":9622,"src":9623,"variant":9135},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[105,9625,9626,9651],{"v-slot:right":107},[21,9627,9628,9631,9634,9642,9648],{},[24,9629,9630],{},"Installation can take a while",[24,9632,9633],{},"High CPU during install is normal",[24,9635,9636,9637,9639,9640],{},"If install struggles at ",[262,9638,8801],{},", recreate the VM with ",[262,9641,8809],{},[24,9643,9644,9645,9647],{},"Keep the course target at ",[262,9646,8801],{}," after setup if possible",[24,9649,9650],{},"Reboot once complete",[2270,9652,9653],{"type":3545},[37,9654,9655],{},"These target resources stay close to common cloud free-tier VMs",[37,9657,2278],{},[11,9659,9661,9665,9668],{"id":9660,"level":14},"step-2-networking",[16,9662,9664],{"id":9663},"virtualbox-configure-networking","VirtualBox: Configure Networking",[37,9666,9667],{},"Use one NAT adapter with port forwarding:",[21,9669,9670,9676,9685,9693,9698],{},[24,9671,9672,9673],{},"VM internet: ",[262,9674,9675],{},"NAT",[24,9677,9678,9679,9682,9683],{},"Host SSH: host ",[262,9680,9681],{},"22"," -> guest ",[262,9684,9681],{},[24,9686,9687,9688,9682,9691],{},"Host browser: host ",[262,9689,9690],{},"3000",[262,9692,8280],{},[24,9694,1493,9695,9697],{},[262,9696,8498],{}," from the host computer",[24,9699,9700],{},"See the slides below for adapter and port-forwarding screens",[11,9702,9704,9708,9721],{"id":9703,"level":95},"adapter-settings-screen",[16,9705,9707],{"id":9706},"adapter-settings","Adapter Settings",[21,9709,9710,9713,9718],{},[24,9711,9712],{},"Adapter 1 enabled",[24,9714,9715,9716],{},"Attached to ",[262,9717,9675],{},[24,9719,9720],{},"No second adapter needed for the baseline path",[37,9722,9723],{},[140,9724],{"alt":9725,"src":9726,"variant":9135},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,9728,9730,9734,9762],{"id":9729,"level":95},"port-forwarding-screen",[16,9731,9733],{"id":9732},"port-forwarding","Port Forwarding",[21,9735,9736,9744,9751],{},[24,9737,9738,9739,9741,9742],{},"SSH: host ",[262,9740,9681],{}," to guest ",[262,9743,9681],{},[24,9745,9746,9747,9741,9749],{},"Apache HTTP: host ",[262,9748,9690],{},[262,9750,8280],{},[24,9752,9753,9754,9756,9757,9741,9760],{},"If host ",[262,9755,9681],{}," is already busy, use host ",[262,9758,9759],{},"2222",[262,9761,9681],{},[37,9763,9764],{},[140,9765],{"alt":9766,"src":9767,"variant":9135},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,9769,9771,9775,9778,9781,9784,9787],{"id":9770,"level":14},"step-3-connect-ssh",[16,9772,9774],{"id":9773},"step-3-connect-with-ssh","Step 3: Connect With SSH",[37,9776,9777],{},"Run from your host terminal:",[1227,9779],{"language":1229,"src":9780},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[37,9782,9783],{},"First connection prompt:",[1227,9785],{"language":4008,"src":9786},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[21,9788,9789,9796,9805,9808,9811],{},[24,9790,9791,9792,9795],{},"Replace ",[262,9793,9794],{},"your_ucid"," with your UCID",[24,9797,9798,9799,9801,9802,9804],{},"Type ",[262,9800,3472],{}," once for this course VM on ",[262,9803,8498],{}," (if prompted like the example above)",[24,9806,9807],{},"Enter your Ubuntu password",[24,9809,9810],{},"After login, commands run inside Ubuntu",[24,9812,9813,1544,9816,9819],{},[262,9814,9815],{},"exit",[262,9817,9818],{},"logout"," disconnects from the VM",[11,9821,9823,9827,9830],{"id":9822,"level":14},"step-4-confirm-network",[16,9824,9826],{"id":9825},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[37,9828,9829],{},"Run inside Ubuntu through SSH:",[100,9831,9832,9874],{"gap":102,"left-width":2598,"right-width":103,"stack":2054},[105,9833,9834,9837,9840],{"v-slot:left":107},[37,9835,9836],{},"Network check:",[1227,9838],{"language":1229,"src":9839},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[21,9841,9842,9848,9854,9860,9866],{},[24,9843,9844,9847],{},[262,9845,9846],{},"ping",": confirms basic network access",[24,9849,9850,9853],{},[262,9851,9852],{},"-c 4",": stop after four replies",[24,9855,9856,9859],{},[262,9857,9858],{},"apt update",": refreshes package indexes",[24,9861,9862,9865],{},[262,9863,9864],{},"apt upgrade",": applies available package updates",[24,9867,2515,9868,9870,9871],{},[262,9869,9846],{}," is not found, run ",[262,9872,9873],{},"sudo apt install iputils-ping",[105,9875,9876,9879,9882],{"v-slot:right":107},[37,9877,9878],{},"Port-forwarding check:",[1227,9880],{"language":1229,"src":9881},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[21,9883,9884,9889,9892,9896],{},[24,9885,9886,9887],{},"The VM may show ",[262,9888,9322],{},[24,9890,9891],{},"That is normal for VirtualBox NAT",[24,9893,1493,9894,9697],{},[262,9895,8498],{},[24,9897,9898],{},"Port forwarding routes host traffic into the VM",[11,9900,9902,9906],{"id":9901,"level":14},"step-5-shared-folder",[16,9903,9905],{"id":9904},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[100,9907,9908,9942],{"gap":102,"left-width":2053,"right-width":2598,"stack":2054},[105,9909,9910,9913],{"v-slot:left":107},[37,9911,9912],{},"In VirtualBox:",[21,9914,9915,9918,9921,9924,9927,9930,9933,9936,9939],{},[24,9916,9917],{},"Open VM settings",[24,9919,9920],{},"Choose Shared Folders",[24,9922,9923],{},"Folder Path: your cloned course repository folder",[24,9925,9926],{},"Folder Name: a simple repo name with no spaces",[24,9928,9929],{},"Mount Point: leave blank",[24,9931,9932],{},"Read-only: off",[24,9934,9935],{},"Auto-mount: on",[24,9937,9938],{},"Make Machine-permanent: on",[24,9940,9941],{},"Make Global: off",[105,9943,9944],{"v-slot:right":107},[37,9945,9946],{},[140,9947],{"alt":9948,"src":9949,"variant":144},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,9951,9953,9957,9960,9963],{"id":9952,"level":14},"step-6-guest-additions",[16,9954,9956],{"id":9955},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[37,9958,9959],{},"Run inside Ubuntu:",[1227,9961],{"language":1229,"src":9962},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[21,9964,9965,9972,9978],{},[24,9966,2705,9967,2671,9969,9971],{},[262,9968,9858],{},[262,9970,9864],{}," first only if you skipped the Step 4 updates",[24,9973,9974,9977],{},[262,9975,9976],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[24,9979,9980],{},"Reboot after the group step on the next slide",[11,9982,9984,9988,9991,9994],{"id":9983,"level":95},"step-6b-confirm-vboxsf",[16,9985,9987],{"id":9986},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[37,9989,9990],{},"Reconnect with SSH, then run inside Ubuntu:",[1227,9992],{"language":1229,"src":9993},"\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",[21,9995,9996,10002,10008],{},[24,9997,9998,10001],{},[262,9999,10000],{},"ls \u002Fmedia",": shows available mounted folders",[24,10003,10004,10007],{},[262,10005,10006],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[24,10009,10010],{},"Permission denied is common the first time",[11,10012,10014,10018,10021,10024],{"id":10013,"level":14},"step-7-locate-share",[16,10015,10017],{"id":10016},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[37,10019,10020],{},"If the shared folder exists but says permission denied:",[1227,10022],{"language":1229,"src":10023},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[21,10025,10026,10032,10038],{},[24,10027,10028,10031],{},[262,10029,10030],{},"vboxsf",": group allowed to read VirtualBox shared folders",[24,10033,10034,10037],{},[262,10035,10036],{},"$USER",": your Ubuntu login user for terminal access",[24,10039,10040],{},"Reboot applies the shared-folder support and new group membership",[11,10042,10044,10048,10050,10053,10070,10073],{"id":10043,"level":95},"step-7b-locate-share",[16,10045,10047],{"id":10046},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[37,10049,9990],{},[1227,10051],{"language":1229,"src":10052},"\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",[21,10054,10055,10061,10067],{},[24,10056,10057,10060],{},[262,10058,10059],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[24,10062,10063,10066],{},[262,10064,10065],{},"\u003Cshared-folder>",": your shared course repo folder name",[24,10068,10069],{},"Use the folder that points to your repository",[37,10071,10072],{},"Expected repo folders:",[21,10074,10075,10079,10083,10087],{},[24,10076,10077],{},[262,10078,1167],{},[24,10080,10081],{},[262,10082,5875],{},[24,10084,10085],{},[262,10086,5878],{},[24,10088,10089],{},[262,10090,5881],{},[11,10092,10094,10098,10113],{"id":10093,"level":95},"step-7-2-shared-folder-check",[16,10095,10097],{"id":10096},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[21,10099,10100,10103,10110],{},[24,10101,10102],{},"Edit a small file from VS Code on host",[24,10104,2705,10105,1544,10107,10109],{},[262,10106,1156],{},[262,10108,1376],{}," inside Ubuntu",[24,10111,10112],{},"Confirm Ubuntu sees the same file content",[37,10114,10115],{},"If the file does not match, stop and fix the share before Apache setup",[11,10117,10119,10123,10125,10128],{"id":10118,"level":14},"step-8-install-apache-php-mysql",[16,10120,10122],{"id":10121},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[37,10124,9959],{},[1227,10126],{"language":1229,"src":10127},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[21,10129,10130,10136,10141,10147,10153,10159],{},[24,10131,10132,10135],{},[262,10133,10134],{},"apache2",": web server",[24,10137,10138,10140],{},[262,10139,5668],{},": PHP runtime",[24,10142,10143,10146],{},[262,10144,10145],{},"libapache2-mod-php",": lets Apache execute PHP files",[24,10148,10149,10152],{},[262,10150,10151],{},"mysql-server",": local MySQL database server",[24,10154,10155,10158],{},[262,10156,10157],{},"php-mysql",": lets PHP connect to MySQL",[24,10160,2705,10161,2671,10163,10165],{},[262,10162,9858],{},[262,10164,9864],{}," first only if they have not been run recently",[11,10167,10169,10173,10180],{"id":10168,"level":95},"optional-swap-check",[16,10170,10172],{"id":10171},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[37,10174,10175,10176,10179],{},"Ubuntu usually has swap already. Only add this if ",[262,10177,10178],{},"swapon --show"," prints nothing.",[100,10181,10182,10196],{"gap":102,"left-width":103,"right-width":103},[105,10183,10184,10187,10190,10193],{"v-slot:left":107},[37,10185,10186],{},"Check first:",[1227,10188],{"language":1229,"src":10189},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[37,10191,10192],{},"Add a small swap file only if swap is off:",[1227,10194],{"language":1229,"src":10195},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[105,10197,10198],{"v-slot:right":107},[21,10199,10200,10203,10208,10211],{},[24,10201,10202],{},"Swap gives Ubuntu emergency disk-backed memory",[24,10204,10205,10206],{},"It helps when installs or MySQL briefly need more than ",[262,10207,8801],{},[24,10209,10210],{},"It is slower than RAM, so it is not a performance upgrade",[24,10212,10213],{},"Do not run the setup again if swap already exists",[11,10215,10217,10221,10227],{"id":10216,"level":95},"optional-apache-low-memory",[16,10218,10220],{"id":10219},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[37,10222,10223,10224,10226],{},"Use this if the ",[262,10225,8801],{}," VM feels unstable or Apache starts too many PHP workers.",[100,10228,10229,10242],{"gap":102,"left-width":103,"right-width":103},[105,10230,10231,10234,10239],{"v-slot:left":107},[37,10232,10233],{},"Edit Apache prefork settings in:",[37,10235,10236],{},[262,10237,10238],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[1227,10240],{"language":1229,"src":10241},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[105,10243,10244,10247,10251],{"v-slot:right":107},[37,10245,10246],{},"Change the existing values to:",[1227,10248],{"language":10249,"src":10250},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[21,10252,10253,10259,10262,10269],{},[24,10254,10255,10256],{},"Edit the existing lines inside ",[262,10257,10258],{},"\u003CIfModule mpm_prefork_module>",[24,10260,10261],{},"If a line is missing, add it inside that same block",[24,10263,10264,10265,10268],{},"Do not paste a second ",[262,10266,10267],{},"\u003CIfModule>"," block",[24,10270,10271],{},"Restart Apache after config changes",[11,10273,10275,10279,10285],{"id":10274,"level":95},"optional-mysql-low-memory",[16,10276,10278],{"id":10277},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[37,10280,10281,10282,10284],{},"Use this only if MySQL struggles on the ",[262,10283,8801],{}," VM.",[100,10286,10287,10300],{"gap":102,"left-width":103,"right-width":103},[105,10288,10289,10292,10297],{"v-slot:left":107},[37,10290,10291],{},"Edit MySQL server settings in:",[37,10293,10294],{},[262,10295,10296],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[1227,10298],{"language":1229,"src":10299},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[105,10301,10302,10308,10311],{"v-slot:right":107},[37,10303,10304,10305,1601],{},"Add or edit these under ",[262,10306,10307],{},"[mysqld]",[1227,10309],{"language":6475,"src":10310},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[21,10312,10313,10319,10324,10327],{},[24,10314,10315,10316,10318],{},"Keep these under the existing ",[262,10317,10307],{}," heading",[24,10320,10321,10322,10318],{},"Do not create a second ",[262,10323,10307],{},[24,10325,10326],{},"If either setting already exists, edit it instead of adding a duplicate",[24,10328,10329],{},"Restart MySQL after config changes",[11,10331,10333,10336,10339,10342],{"id":10332,"level":95},"low-memory-diagnostics",[16,10334,10335],{"id":10332},"Low Memory Diagnostics",[37,10337,10338],{},"Run these after the minor tuning checks:",[1227,10340],{"language":1229,"src":10341},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[21,10343,10344,10350,10355,10361,10368],{},[24,10345,10346,10349],{},[262,10347,10348],{},"free -h",": shows RAM and swap",[24,10351,10352,10354],{},[262,10353,10178],{},": confirms whether swap is active",[24,10356,10357,10360],{},[262,10358,10359],{},"systemctl status",": checks whether Apache and MySQL are running",[24,10362,10363,10364,10367],{},"No output from the ",[262,10365,10366],{},"grep"," line is usually good",[24,10369,10370],{},"Do not tune randomly; change one setting, restart, then retest",[11,10372,10374,10378,10380,10383,10386,10389],{"id":10373,"level":14},"step-9-create-local-mysql-db",[16,10375,10377],{"id":10376},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[37,10379,9959],{},[1227,10381],{"language":1229,"src":10382},"\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",[37,10384,10385],{},"Then run in the MySQL prompt:",[1227,10387],{"language":5881,"src":10388},"\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",[21,10390,10391,10395,10398],{},[24,10392,9791,10393,9795],{},[262,10394,9794],{},[24,10396,10397],{},"Database name and username should match your UCID",[24,10399,10400],{},"Password is local-only unless your instructor says otherwise",[11,10402,10404,10407,10410,10423,10426,10432],{"id":10403,"level":14},"local-vs-remote-database",[16,10405,10406],{"id":10403},"Local Vs Remote Database",[37,10408,10409],{},"This MySQL database is only for local testing:",[21,10411,10412,10416,10418,10420],{},[24,10413,5142,10414],{},[262,10415,8498],{},[24,10417,5157],{},[24,10419,5154],{},[24,10421,10422],{},"Password: your local password",[37,10424,10425],{},"Render uses the instructor-provided remote database connection string",[37,10427,10428,10429],{},"Get that string from ",[41,10430,5168],{"href":5168,"rel":10431},[45],[37,10433,10434],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10436,10438,10442,10444,10447,10449,10452,10455],{"id":10437,"level":14},"step-10-confirm-local-mysql",[16,10439,10441],{"id":10440},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[37,10443,9959],{},[1227,10445],{"language":1229,"src":10446},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[37,10448,4654],{},[1227,10450],{"language":5881,"src":10451},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[37,10453,10454],{},"Expected:",[21,10456,10457,10463],{},[24,10458,10459,10462],{},[262,10460,10461],{},"SELECT DATABASE()"," returns your UCID",[24,10464,10465,10468],{},[262,10466,10467],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10470,10472,10478,10481,10484,10487],{"id":10471,"level":14},"step-11-documentroot",[16,10473,10475,10476],{"id":10474},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[262,10477,1167],{},[37,10479,10480],{},"Apache should serve:",[1227,10482],{"language":4008,"src":10483},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[37,10485,10486],{},"Do not serve the whole repo",[21,10488,10489,10498],{},[24,10490,10491,965,10493,969,10495,10497],{},[262,10492,5875],{},[262,10494,5878],{},[262,10496,5881],{}," stay outside the web root",[24,10499,10500,10502],{},[262,10501,1167],{}," is the browser-facing folder",[11,10504,10506,10510,10513,10518,10520,10525,10528,10531],{"id":10505,"level":95},"apache-site-config",[16,10507,10509],{"id":10508},"step-111-apache-site-config","Step 11.1: Apache Site Config",[37,10511,10512],{},"Create or edit this Apache site config file inside Ubuntu:",[37,10514,10515],{},[262,10516,10517],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[37,10519,1225],{},[37,10521,10522],{},[262,10523,10524],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[37,10526,10527],{},"Add this content to that file:",[1227,10529],{"language":10249,"src":10530},"\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",[21,10532,10533,10538,10544,10549],{},[24,10534,9791,10535,10537],{},[262,10536,10065],{}," with the actual shared folder name",[24,10539,10540,10541],{},"Save the file as ",[262,10542,10543],{},"it202.conf",[24,10545,10546,10547],{},"Apache listens on guest port ",[262,10548,8280],{},[24,10550,10551,10552],{},"Host browser reaches it through ",[262,10553,8356],{},[11,10555,10557,10561,10563,10566],{"id":10556,"level":95},"enable-site",[16,10558,10560],{"id":10559},"step-112-enable-the-site","Step 11.2: Enable The Site",[37,10562,9959],{},[1227,10564],{"language":1229,"src":10565},"\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",[21,10567,10568,10574,10580,10586,10594,10600],{},[24,10569,10570,10573],{},[262,10571,10572],{},"a2ensite",": enable a site config",[24,10575,10576,10579],{},[262,10577,10578],{},"a2dissite",": disable a site config",[24,10581,10582,10585],{},[262,10583,10584],{},"www-data",": Apache's user for browser requests",[24,10587,10588,10589,6628,10591,10593],{},"Adding ",[262,10590,10584],{},[262,10592,10030],{}," lets Apache read the shared folder",[24,10595,10596,10599],{},[262,10597,10598],{},"configtest",": check syntax before reload",[24,10601,10602,10605],{},[262,10603,10604],{},"restart",": applies the Apache user group change",[11,10607,10609,10613,10616,10619,10622],{"id":10608,"level":14},"step-12-php-check-page",[16,10610,10612],{"id":10611},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[37,10614,10615],{},"Create this file on the host:",[1227,10617],{"language":4008,"src":10618},"\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",[37,10620,10621],{},"Example content:",[1227,10623],{"language":5668,"src":10624},"\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,10626,10628,10631,10634,10637,10639],{"id":10627,"level":14},"final-browser-check",[16,10629,10630],{"id":10627},"Final Browser Check",[37,10632,10633],{},"Open from host browser:",[1227,10635],{"language":4008,"src":10636},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[37,10638,10454],{},[21,10640,10641,10644,10647,10650],{},[24,10642,10643],{},"Message appears",[24,10645,10646],{},"Time appears",[24,10648,10649],{},"PHP code is not shown as raw text",[24,10651,10652],{},"Editing the file on host changes output after refresh",[11,10654,10656,10659],{"id":10655,"level":14},"common-problems",[16,10657,10658],{"id":10655},"Common Problems",[21,10660,10661,10664,10667,10672,10675,10688,10698],{},[24,10662,10663],{},"Browser timeout: missing or wrong port-forwarding rule",[24,10665,10666],{},"Connection refused: Apache not running",[24,10668,10669,10670],{},"No internet in VM: check Adapter 1 is still ",[262,10671,9675],{},[24,10673,10674],{},"Shared folder missing: check Auto-mount and guest utilities",[24,10676,10677,10678,10681,10682,10684,10685,10687],{},"Browser shows ",[262,10679,10680],{},"403 Forbidden",": confirm ",[262,10683,10584],{}," is in ",[262,10686,10030],{},", then restart Apache or reboot",[24,10689,10690,10691,10694,10695,10697],{},"Permission denied on ",[262,10692,10693],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[262,10696,10030],{}," and reboot",[24,10699,10700],{},"Raw PHP code: PHP module not running through Apache",[11,10702,10704,10707,10710],{"id":10703,"level":14},"recovery-routine",[16,10705,10706],{"id":10703},"Recovery Routine",[37,10708,10709],{},"Check in this order:",[159,10711,10712,10715,10721,10727,10732,10740,10747,10753,10758,10767],{},[24,10713,10714],{},"VM is running",[24,10716,10717,10720],{},[262,10718,10719],{},"ping github.com"," works inside Ubuntu",[24,10722,10723,10726],{},[262,10724,10725],{},"ssh username@localhost"," works from host",[24,10728,10729,10731],{},[262,10730,10006],{}," shows the shared repo",[24,10733,10734,10737,10738],{},[262,10735,10736],{},"groups"," includes ",[262,10739,10030],{},[24,10741,10742,10737,10745],{},[262,10743,10744],{},"id www-data",[262,10746,10030],{},[24,10748,10749,10752],{},[262,10750,10751],{},"sudo systemctl status apache2"," is active",[24,10754,10755,10752],{},[262,10756,10757],{},"sudo systemctl status mysql",[24,10759,10760,10763,10764],{},[262,10761,10762],{},"sudo apache2ctl configtest"," says ",[262,10765,10766],{},"Syntax OK",[24,10768,10769,10772],{},[262,10770,10771],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,10774,10775,10777],{"id":1798,"level":14},[16,10776,1799],{"id":1798},[100,10778,10779,10820],{"gap":102,"left-width":103,"right-width":103},[105,10780,10781,10783,10789,10798,10803,10809,10815],{"v-slot:left":107},[361,10782,1807],{"id":1806},[37,10784,10785,10788],{},[122,10786,10787],{},"VM"," - separate computer running inside your host computer",[37,10790,10791,10794,10795,10797],{},[122,10792,10793],{},"Port forwarding"," - host ",[262,10796,8498],{}," traffic routed into the VM",[37,10799,10800,10802],{},[122,10801,10030],{}," - VirtualBox shared-folder permission group",[37,10804,10805,10808],{},[122,10806,10807],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[37,10810,10811,10814],{},[122,10812,10813],{},"DocumentRoot"," - folder Apache serves to browsers",[37,10816,10817,10819],{},[122,10818,9675],{}," - VM network mode that gives the VM outbound internet access",[105,10821,10822,10824],{"v-slot:right":107},[361,10823,1838],{"id":1795},[21,10825,10826,10832,10839,10846,10853,10860,10866],{},[24,10827,10828],{},[41,10829,10831],{"href":8422,"rel":10830},[45],"VirtualBox Downloads",[24,10833,10834],{},[41,10835,10838],{"href":10836,"rel":10837},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[45],"VirtualBox Manual: Host And Guest Combinations",[24,10840,10841],{},[41,10842,10845],{"href":10843,"rel":10844},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[45],"VirtualBox Manual: Installation",[24,10847,10848],{},[41,10849,10852],{"href":10850,"rel":10851},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[45],"VirtualBox Manual: Shared Folders",[24,10854,10855],{},[41,10856,10859],{"href":10857,"rel":10858},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[45],"VirtualBox Manual: NAT Port Forwarding",[24,10861,10862],{},[41,10863,10865],{"href":8440,"rel":10864},[45],"Ubuntu Server: Installer",[24,10867,10868],{},[41,10869,10872],{"href":10870,"rel":10871},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[45],"Ubuntu Server: OpenSSH Server",[11,10874,10875,10877,10879],{"id":462,"level":14},[16,10876,465],{"id":462},[37,10878,1868],{},[21,10880,10881,10884,10887,10890,10893,10898],{},[24,10882,10883],{},"Pick the correct Ubuntu ISO for your host CPU",[24,10885,10886],{},"Configure NAT port forwarding",[24,10888,10889],{},"Connect to Ubuntu with SSH",[24,10891,10892],{},"Find the VirtualBox shared repo",[24,10894,10895,10896],{},"Configure Apache to serve ",[262,10897,1167],{},[24,10899,10900],{},"Create a local MySQL database and user named after your UCID",{"title":107,"searchDepth":489,"depth":489,"links":10902},[10903,10904,10905,10906,10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,10950,10951,10952,10953,10954,10955,10956,10957,10958,10959,10961,10962,10963,10964,10965,10966,10967,10968],{"id":8302,"depth":489,"text":8294},{"id":8328,"depth":489,"text":8331},{"id":8373,"depth":489,"text":8376},{"id":981,"depth":489,"text":984},{"id":8478,"depth":489,"text":8481},{"id":8513,"depth":489,"text":8514},{"id":8537,"depth":489,"text":8540},{"id":8569,"depth":489,"text":8572},{"id":8595,"depth":489,"text":8598},{"id":8624,"depth":489,"text":8627},{"id":8656,"depth":489,"text":8657},{"id":8680,"depth":489,"text":8683},{"id":8711,"depth":489,"text":8714},{"id":8742,"depth":489,"text":8743},{"id":8778,"depth":489,"text":8779},{"id":8840,"depth":489,"text":8843},{"id":8875,"depth":489,"text":8878},{"id":8921,"depth":489,"text":8924},{"id":8964,"depth":489,"text":8967},{"id":9008,"depth":489,"text":9011},{"id":9058,"depth":489,"text":9059},{"id":9121,"depth":489,"text":9122},{"id":9157,"depth":489,"text":9158},{"id":9192,"depth":489,"text":9193},{"id":9229,"depth":489,"text":9230},{"id":9262,"depth":489,"text":9263},{"id":9299,"depth":489,"text":9300},{"id":9332,"depth":489,"text":9333},{"id":9362,"depth":489,"text":9363},{"id":9392,"depth":489,"text":9393},{"id":9422,"depth":489,"text":9423},{"id":9452,"depth":489,"text":9453},{"id":9482,"depth":489,"text":9483},{"id":9516,"depth":489,"text":9517},{"id":9548,"depth":489,"text":9549},{"id":9580,"depth":489,"text":9581},{"id":9612,"depth":489,"text":9613},{"id":9663,"depth":489,"text":9664},{"id":9706,"depth":489,"text":9707},{"id":9732,"depth":489,"text":9733},{"id":9773,"depth":489,"text":9774},{"id":9825,"depth":489,"text":9826},{"id":9904,"depth":489,"text":9905},{"id":9955,"depth":489,"text":9956},{"id":9986,"depth":489,"text":9987},{"id":10016,"depth":489,"text":10017},{"id":10046,"depth":489,"text":10047},{"id":10096,"depth":489,"text":10097},{"id":10121,"depth":489,"text":10122},{"id":10171,"depth":489,"text":10172},{"id":10219,"depth":489,"text":10220},{"id":10277,"depth":489,"text":10278},{"id":10332,"depth":489,"text":10335},{"id":10376,"depth":489,"text":10377},{"id":10403,"depth":489,"text":10406},{"id":10440,"depth":489,"text":10441},{"id":10474,"depth":489,"text":10960},"Step 11: Point Apache At public_html",{"id":10508,"depth":489,"text":10509},{"id":10559,"depth":489,"text":10560},{"id":10611,"depth":489,"text":10612},{"id":10627,"depth":489,"text":10630},{"id":10655,"depth":489,"text":10658},{"id":10703,"depth":489,"text":10706},{"id":1798,"depth":489,"text":1799},{"id":462,"depth":489,"text":465},"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":8294,"description":10969},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[10979,10980,10249,10981,10982],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581680834]