[{"data":1,"prerenderedAt":11208},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches":3,"content-page-quiz:none":801,"book-module-total-pages":802,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":803,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches":11207},{"id":4,"title":5,"audience":6,"body":7,"contentType":775,"course":776,"description":777,"estimateBasis":778,"estimatedDiscussionMinutes":779,"estimatedLiveMinutes":780,"estimatedTotalMinutes":781,"extension":782,"meta":783,"module":784,"navigation":785,"order":786,"path":787,"promptAssist":788,"seo":789,"status":790,"stem":791,"tags":792,"videoDuration":796,"videoId":797,"videoLink":798,"videoTitle":799,"week":784,"__hash__":800},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches","student",{"type":8,"value":9,"toc":753},"minimark",[10,55,105,131,198,264,323,373,438,479,574,617,646,715],[11,12,15,19,23],"slide",{"id":13,"level":14},"objectives","2",[16,17,18],"h2",{"id":13},"Objectives",[20,21,22],"p",{},"By the end, you should be able to:",[24,25,26,38,43,47,52],"ul",{},[27,28,29,30,34,35],"li",{},"Understand the purpose and usage of ",[31,32,33],"code",{},"qa"," and ",[31,36,37],{},"prod",[27,39,40,41],{},"Create and push ",[31,42,33],{},[27,44,40,45],{},[31,46,37],{},[27,48,49,50],{},"Keep local work pointed at ",[31,51,33],{},[27,53,54],{},"Confirm GitHub has the expected branches",[11,56,58,61,97],{"id":57,"level":14},"branch-roles",[16,59,60],{"id":57},"Branch Roles",[24,62,63,74,84,94],{},[27,64,65,68,69],{},[31,66,67],{},"main",": starter baseline and shared source branch\n",[24,70,71],{},[27,72,73],{},"Most projects stick with this; we'll split ours into development lanes",[27,75,76,78,79],{},[31,77,33],{},": public testing and evidence branch\n",[24,80,81],{},[27,82,83],{},"Normal branch to return to before new course work",[27,85,86,88,89],{},[31,87,37],{},": stable grading and evaluation branch\n",[24,90,91],{},[27,92,93],{},"Protected from everyday local edits",[27,95,96],{},"Later deployment setup connects Render to these branches",[20,98,99,100,102,103],{},"Course flow: feature or homework branch -> ",[31,101,33],{}," -> ",[31,104,37],{},[11,106,108,111,114,120],{"id":107,"level":14},"before-you-start",[16,109,110],{"id":107},"Before You Start",[20,112,113],{},"Run inside the course repository:",[115,116],"code-snippet",{"label":117,"language":118,"src":119},"before-you-start.sh","bash","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[24,121,122,125,128],{},[27,123,124],{},"Working tree should be clean",[27,126,127],{},"Starter baseline already pushed to GitHub",[27,129,130],{},"Stop if Git says files are modified or untracked",[11,132,134,140],{"id":133,"level":14},"step-1-sync-main",[16,135,137,138],{"id":136},"step-1-start-from-main","Step 1: Start From ",[31,139,67],{},[141,142,145,156],"two-col",{"gap":143,"left-width":144,"right-width":144},"lg","1fr",[146,147,149,152],"template",{"v-slot:left":148},"",[20,150,151],{},"Run:",[115,153],{"label":154,"language":118,"src":155},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[146,157,158,161,166],{"v-slot:right":148},[20,159,160],{},"Example output:",[115,162],{"label":163,"language":164,"src":165},"example-output.txt","text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[24,167,168,176],{},[27,169,170,173,174],{},[31,171,172],{},"git checkout main",": switch to ",[31,175,67],{},[27,177,178,181,182,184,185],{},[31,179,180],{},"git pull origin main",": get the latest ",[31,183,67],{}," from GitHub\n",[24,186,187,193],{},[27,188,189,192],{},[31,190,191],{},"origin",": GitHub remote",[27,194,195,197],{},[31,196,67],{},": remote branch being pulled",[11,199,201,207],{"id":200,"level":14},"step-2-create-qa",[16,202,204,205],{"id":203},"step-2-create-and-push-qa","Step 2: Create And Push ",[31,206,33],{},[141,208,209,217],{"gap":143,"left-width":144,"right-width":144},[146,210,211,213],{"v-slot:left":148},[20,212,151],{},[115,214],{"label":215,"language":118,"src":216},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[146,218,219,221,224],{"v-slot:right":148},[20,220,160],{},[115,222],{"label":163,"language":164,"src":223},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[24,225,226,243],{},[27,227,228,231,232,234,235],{},[31,229,230],{},"git checkout -b qa",": create ",[31,233,33],{}," and switch to it\n",[24,236,237],{},[27,238,239,242],{},[31,240,241],{},"-b",": creates a new branch of the following name",[27,244,245,248,249,251,252],{},[31,246,247],{},"git push -u origin qa",": send ",[31,250,33],{}," to GitHub\n",[24,253,254],{},[27,255,256,259,260,263],{},[31,257,258],{},"-u",": remember ",[31,261,262],{},"origin\u002Fqa"," as the upstream branch",[11,265,267,273],{"id":266,"level":14},"step-3-create-prod",[16,268,270,271],{"id":269},"step-3-create-and-push-prod","Step 3: Create And Push ",[31,272,37],{},[141,274,275,283],{"gap":143,"left-width":144,"right-width":144},[146,276,277,279],{"v-slot:left":148},[20,278,151],{},[115,280],{"label":281,"language":118,"src":282},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[146,284,285,287,290],{"v-slot:right":148},[20,286,160],{},[115,288],{"label":163,"language":164,"src":289},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[24,291,292,301,306,318],{},[27,293,294,295,297,298,300],{},"Create ",[31,296,37],{}," from the current ",[31,299,33],{}," branch",[27,302,303],{},[31,304,305],{},"git checkout -b prod",[27,307,308,309,251,311],{},"Push ",[31,310,37],{},[24,312,313],{},[27,314,315],{},[31,316,317],{},"git push origin prod",[27,319,320,322],{},[31,321,37],{}," starts from the same clean baseline",[11,324,326,331],{"id":325,"level":14},"step-4-return-to-qa",[16,327,328,329],{"id":325},"Step 4: Return To ",[31,330,33],{},[141,332,333,341],{"gap":143,"left-width":144,"right-width":144},[146,334,335,337],{"v-slot:left":148},[20,336,151],{},[115,338],{"label":339,"language":118,"src":340},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[146,342,343,345,348],{"v-slot:right":148},[20,344,160],{},[115,346],{"label":163,"language":164,"src":347},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[24,349,350,355,360],{},[27,351,352,354],{},[31,353,33],{}," should have the asterisk",[27,356,357,359],{},[31,358,37],{}," should still exist on GitHub",[27,361,362,363,365],{},"Do not start normal course work from ",[31,364,37],{},[24,366,367],{},[27,368,369,370,372],{},"We'll remove local ",[31,371,37],{}," to avoid this issue",[11,374,376,382],{"id":375,"level":14},"step-5-delete-local-prod",[16,377,379,380],{"id":378},"step-5-remove-local-prod","Step 5: Remove Local ",[31,381,37],{},[141,383,384,392],{"gap":143,"left-width":144,"right-width":144},[146,385,386,388],{"v-slot:left":148},[20,387,151],{},[115,389],{"label":390,"language":118,"src":391},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[146,393,394,396,399],{"v-slot:right":148},[20,395,160],{},[115,397],{"label":163,"language":164,"src":398},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[24,400,401,423],{},[27,402,403,406,407,409],{},[31,404,405],{},"git branch -d prod",": delete local ",[31,408,37],{},[24,410,411,417],{},[27,412,413,416],{},[31,414,415],{},"-d",": delete only if Git considers it safe",[27,418,419,422],{},[31,420,421],{},"-D",": can be used as a forced delete",[27,424,425,428,429],{},[31,426,427],{},"git branch -r",": list remote branches\n",[24,430,431],{},[27,432,433,434,437],{},"Confirms ",[31,435,436],{},"origin\u002Fprod"," still exists",[11,439,441,444,447,450,464,467],{"id":440,"level":14},"github-check",[16,442,443],{"id":440},"GitHub Check",[20,445,446],{},"Open the branch dropdown on GitHub",[20,448,449],{},"You should see:",[24,451,452,456,460],{},[27,453,454],{},[31,455,67],{},[27,457,458],{},[31,459,33],{},[27,461,462],{},[31,463,37],{},[20,465,466],{},"Branch roles:",[24,468,469,474],{},[27,470,471,473],{},[31,472,33],{},": testing and evidence",[27,475,476,478],{},[31,477,37],{},": stable grading target",[11,480,482,486],{"id":481,"level":14},"normal-workflow",[16,483,485],{"id":484},"normal-workflow-after-setup","Normal Workflow After Setup",[487,488,489,506,514,526,531,545,548,556,568],"ol",{},[27,490,491,492,494],{},"Return to ",[31,493,33],{},[24,495,496,501],{},[27,497,498],{},[31,499,500],{},"git checkout qa",[27,502,503],{},[31,504,505],{},"git pull origin qa",[27,507,508,509],{},"Create a feature or homework branch\n",[24,510,511],{},[27,512,513],{},"Branch name matches the task",[27,515,516,517],{},"Commit the work on that branch\n",[24,518,519],{},[27,520,521,522,525],{},"Check ",[31,523,524],{},"git status"," before each Git command",[27,527,528,529],{},"Push the branch and open a pull request into ",[31,530,33],{},[27,532,533,534,536,537],{},"Merge into ",[31,535,33],{}," after review\n",[24,538,539],{},[27,540,541,542,544],{},"QA deployment will update from ",[31,543,33],{}," after Render setup",[27,546,547],{},"Test the QA version",[27,549,550,551,553,554],{},"Open a pull request from ",[31,552,33],{}," into ",[31,555,37],{},[27,557,533,558,560,561],{},[31,559,37],{}," when stable\n",[24,562,563],{},[27,564,565,566,544],{},"Production deployment will use ",[31,567,37],{},[27,569,570,571,573],{},"Return locally to ",[31,572,33],{}," and pull before the next task",[11,575,577,580],{"id":576,"level":14},"common-mistakes",[16,578,579],{"id":576},"Common Mistakes",[24,581,582,587,592,600,608,611],{},[27,583,584,585],{},"Working directly on ",[31,586,37],{},[27,588,589,590],{},"Forgetting to return to ",[31,591,33],{},[27,593,594,595,597,598],{},"Pushing ",[31,596,33],{}," but not ",[31,599,37],{},[27,601,602,603,605,606],{},"Deleting remote ",[31,604,37],{}," instead of local ",[31,607,37],{},[27,609,610],{},"Assuming GitHub has the branch without checking",[27,612,613,614,616],{},"Starting new work before ",[31,615,524],{}," is clean",[11,618,620,623,626],{"id":619,"level":14},"quick-check",[16,621,622],{"id":619},"Quick Check",[20,624,625],{},"Answer before moving on:",[24,627,628,631,634,637,643],{},[27,629,630],{},"Which branch should QA deployment watch?",[27,632,633],{},"Which branch should production grading use?",[27,635,636],{},"Which branch should you return to before new work?",[27,638,639,640,642],{},"Why remove local ",[31,641,37],{}," after pushing it?",[27,644,645],{},"What future setup connects Render to these branches?",[11,647,649,653],{"id":648,"level":14},"further-learning",[16,650,652],{"id":651},"key-terms-and-further-learning","Key Terms And Further Learning",[141,654,655,683],{"gap":143,"left-width":144,"right-width":144},[146,656,657,662],{"v-slot:left":148},[658,659,661],"h3",{"id":660},"key-terms","Key Terms",[24,663,664,667,670,675,680],{},[27,665,666],{},"Branch: named line of Git history",[27,668,669],{},"Upstream: remote branch Git remembers for push\u002Fpull",[27,671,672,674],{},[31,673,33],{},": public testing branch",[27,676,677,679],{},[31,678,37],{},": stable grading branch",[27,681,682],{},"Remote-only branch: exists on GitHub, not locally",[146,684,685,688],{"v-slot:right":148},[658,686,687],{"id":648},"Further Learning",[24,689,690,700,707],{},[27,691,692,693],{},"GitHub Docs: ",[694,695,699],"a",{"href":696,"rel":697},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[698],"nofollow","About branches",[27,701,692,702],{},[694,703,706],{"href":704,"rel":705},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[698],"About pull requests",[27,708,709,710],{},"Pro Git Book: ",[694,711,714],{"href":712,"rel":713},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[698],"Git Branching",[11,716,718,721,724],{"id":717,"level":14},"summary",[16,719,720],{"id":717},"Summary",[20,722,723],{},"Before leaving this presentation, confirm you can:",[24,725,726,737,741,745,750],{},[27,727,728,729,731,732,734,735],{},"Explain ",[31,730,67],{},", ",[31,733,33],{},", and ",[31,736,37],{},[27,738,40,739],{},[31,740,33],{},[27,742,40,743],{},[31,744,37],{},[27,746,747,748],{},"Keep local work branched from ",[31,749,33],{},[27,751,752],{},"Verify remote branches on GitHub",{"title":148,"searchDepth":754,"depth":754,"links":755},2,[756,757,758,759,761,763,765,767,769,770,771,772,773,774],{"id":13,"depth":754,"text":18},{"id":57,"depth":754,"text":60},{"id":107,"depth":754,"text":110},{"id":136,"depth":754,"text":760},"Step 1: Start From main",{"id":203,"depth":754,"text":762},"Step 2: Create And Push qa",{"id":269,"depth":754,"text":764},"Step 3: Create And Push prod",{"id":325,"depth":754,"text":766},"Step 4: Return To qa",{"id":378,"depth":754,"text":768},"Step 5: Remove Local prod",{"id":440,"depth":754,"text":443},{"id":484,"depth":754,"text":485},{"id":576,"depth":754,"text":579},{"id":619,"depth":754,"text":622},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"presentation","Internet Applications","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.","15","40","55","md",{},"1",true,"70","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",false,{"title":5,"description":777},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[793,794,33,795],"git","branches","production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",null,[],[804,1303,2366,3252,4344,5272,6061,7123,7686,8511],{"id":805,"title":806,"audience":6,"body":807,"contentType":775,"course":776,"description":1283,"estimateBasis":1284,"estimatedDiscussionMinutes":1285,"estimatedLiveMinutes":1286,"estimatedTotalMinutes":1287,"extension":782,"meta":1288,"module":784,"navigation":785,"order":1289,"path":1290,"promptAssist":788,"seo":1291,"status":790,"stem":1292,"tags":1293,"videoDuration":1298,"videoId":1299,"videoLink":1300,"videoTitle":1301,"week":784,"__hash__":1302},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":808,"toc":1267},[809,843,883,931,980,1028,1061,1123,1164,1214,1241],[11,810,812,816,830],{"id":811,"level":14},"learn-courses-flow",[16,813,815],{"id":814},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[24,817,818,821,824,827],{},[27,819,820],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[27,822,823],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[27,825,826],{},"The goal is to keep tasks clear and objective for students and grading",[27,828,829],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[20,831,832,833,837,838,842],{},"NOTE: Summer 2026 the previous Learn Platform (",[694,834,835],{"href":835,"rel":836},"https:\u002F\u002Flearn.ethereallab.app",[698],") has been replaced by Learn Courses Platform (",[694,839,840],{"href":840,"rel":841},"https:\u002F\u002Fcourses.ethereallab.app",[698],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,844,846,849,852,880],{"id":845,"level":14},"learn-courses-title",[16,847,806],{"id":848},"learn-courses-platform-and-discord",[20,850,851],{},"How to join:",[24,853,854,860,868,871,874,877],{},[27,855,856,857],{},"Visit the platform ",[694,858,840],{"href":840,"rel":859},[698],[27,861,862,863],{},"Sign in with your NJIT email\n",[24,864,865],{},[27,866,867],{},"If you're in the Canvas course, you should automatically get synced to this platform",[27,869,870],{},"Visit your Profile page",[27,872,873],{},"Associate your Discord account",[27,875,876],{},"Join the course Discord server",[27,878,879],{},"Verify that your course channels appear on Discord",[20,881,882],{},"You can follow the steps on the below slides for guidance",[11,884,887,890],{"id":885,"level":886},"visit-learn-courses","3",[16,888,889],{"id":885},"Visit Learn Courses",[141,891,892,921],{"gap":143,"left-width":144,"right-width":144},[146,893,894,897,902],{"v-slot:left":148},[20,895,896],{},"Go to:",[20,898,899],{},[694,900,840],{"href":840,"rel":901},[698],[24,903,904,912,915,918],{},[27,905,906,907,911],{},"Click the ",[908,909,910],"strong",{},"Login"," button",[27,913,914],{},"Use your NJIT email",[27,916,917],{},"Only NJIT accounts are allowed",[27,919,920],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[146,922,923],{"v-slot:right":148},[20,924,925],{},[926,927],"img",{"alt":928,"src":929,"variant":930},"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,932,934,937],{"id":933,"level":886},"associate-discord-name",[16,935,936],{"id":933},"Associate Discord Name",[141,938,939,964],{"gap":143,"left-width":144,"right-width":144},[146,940,941,944,961],{"v-slot:left":148},[20,942,943],{},"On Learn Courses:",[487,945,946,949,955,958],{},[27,947,948],{},"Open your Profile",[27,950,951,952],{},"Click ",[908,953,954],{},"Refresh Discord Username",[27,956,957],{},"Authorize the Discord prompt",[27,959,960],{},"After the success message appears, save your profile",[20,962,963],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[146,965,966,973],{"v-slot:right":148},[20,967,968],{},[926,969],{"alt":970,"src":971,"variant":930,"max-height":972},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[20,974,975],{},[926,976],{"alt":977,"src":978,"variant":930,"max-height":979},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,981,983,986],{"id":982,"level":886},"authorize-discord",[16,984,985],{"id":982},"Authorize Discord",[141,987,988,1012],{"gap":143,"left-width":144,"right-width":144},[146,989,990,993],{"v-slot:left":148},[20,991,992],{},"Discord will ask whether Learn Courses can access your Discord account.",[24,994,995,998,1003,1006,1009],{},[27,996,997],{},"Confirm you are signed in to the correct Discord account",[27,999,951,1000],{},[908,1001,1002],{},"Authorize",[27,1004,1005],{},"Return to Learn Courses",[27,1007,1008],{},"Look for the success message",[27,1010,1011],{},"Save the profile change",[146,1013,1014,1021],{"v-slot:right":148},[20,1015,1016],{},[926,1017],{"alt":1018,"src":1019,"variant":930,"max-height":1020},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[20,1022,1023],{},[926,1024],{"alt":1025,"src":1026,"variant":930,"max-height":1027},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,1029,1031,1034,1037,1043,1050],{"id":1030,"level":886},"join-the-channel",[16,1032,1033],{"id":1030},"Join The Channel",[20,1035,1036],{},"Use the Discord link provided on Canvas, or use:",[20,1038,1039],{},[694,1040,1041],{"href":1041,"rel":1042},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[698],[20,1044,1045,1046,1049],{},"This should send you to the ",[31,1047,1048],{},"access-channel"," channel.",[24,1051,1052,1055,1058],{},[27,1053,1054],{},"Other channels are protected by a bot",[27,1056,1057],{},"Messages may be blocked until your name and role are set",[27,1059,1060],{},"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,1062,1064,1067],{"id":1063,"level":14},"verify-with-quackbot",[16,1065,1066],{"id":1063},"Verify With QuackBot",[141,1068,1069,1114],{"gap":143,"left-width":144,"right-width":144},[146,1070,1071,1083,1089,1094,1097,1111],{"v-slot:left":148},[24,1072,1073,1076],{},[27,1074,1075],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[27,1077,1078,1079,1082],{},"If you don't see the proper semester category (i.e., ",[31,1080,1081],{},"summer-2026",") or the expected channels you can do the below action",[20,1084,1085,1086,1088],{},"In ",[31,1087,1048],{},", enter:",[20,1090,1091],{},[31,1092,1093],{},"@QuackBot",[20,1095,1096],{},"QuackBot will:",[24,1098,1099,1102,1105,1108],{},[27,1100,1101],{},"Verify your account",[27,1103,1104],{},"Pull in your name and section",[27,1106,1107],{},"Apply your class role",[27,1109,1110],{},"Update your server nickname",[20,1112,1113],{},"This does not change your real Discord username.",[146,1115,1116],{"v-slot:right":148},[20,1117,1118],{},[926,1119],{"alt":1120,"src":1121,"variant":930,"max-height":1122},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,1124,1126,1130,1133,1144,1148],{"id":1125,"level":14},"welcome-and-potential-issues",[16,1127,1129],{"id":1128},"welcome","Welcome",[20,1131,1132],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[24,1134,1135,1138,1141],{},[27,1136,1137],{},"It should appear after the general channels",[27,1139,1140],{},"It should include one or more channels for your active courses",[27,1142,1143],{},"Use the correct course channel for class questions and discussion",[658,1145,1147],{"id":1146},"potential-issues","Potential Issues",[24,1149,1150,1153],{},[27,1151,1152],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[27,1154,1155,1156,1159],{},"If there is an issue, email the instructor or DM ",[31,1157,1158],{},"MattToegel",[24,1160,1161],{},[27,1162,1163],{},"Some Discord privacy settings may require a friend request before DMs work",[11,1165,1167,1170],{"id":1166,"level":14},"general-conduct",[16,1168,1169],{"id":1166},"General Conduct",[24,1171,1172,1175,1178,1189,1192,1200,1208,1211],{},[27,1173,1174],{},"Use class-related channels for questions and discussion",[27,1176,1177],{},"Ask general course questions in the channel instead of DM when possible",[27,1179,1180,1181],{},"Do not post screenshots of in-progress assignment solutions\n",[24,1182,1183,1186],{},[27,1184,1185],{},"This would be more ideal for a DM",[27,1187,1188],{},"If you see posted solution-like items don't assume they're correct",[27,1190,1191],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[27,1193,1194,1195],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[24,1196,1197],{},[27,1198,1199],{},"Since repositories should be set to private; repo links are fine to post in the class channel since other students should not have access to them",[27,1201,1202,1203],{},"Keep off-topic items out of class channels\n",[24,1204,1205],{},[27,1206,1207],{},"There are plenty of categorized channels to use and I can always make more",[27,1209,1210],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[27,1212,1213],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,1215,1216,1218,1221],{"id":619,"level":14},[16,1217,622],{"id":619},[20,1219,1220],{},"Before continuing, confirm:",[24,1222,1223,1226,1229,1232,1235,1238],{},[27,1224,1225],{},"You can sign in to Learn Courses with your NJIT email",[27,1227,1228],{},"Your profile is saved",[27,1230,1231],{},"Discord is associated with your Learn Courses profile",[27,1233,1234],{},"You joined the Discord server",[27,1236,1237],{},"QuackBot applied your course role",[27,1239,1240],{},"You can see the correct course channel",[11,1242,1243,1245],{"id":717,"level":14},[16,1244,720],{"id":717},[24,1246,1247,1250,1258,1261,1264],{},[27,1248,1249],{},"Learn Courses supports course tools and course-specific setup",[27,1251,1252,1253],{},"Canvas remains the official assignment, grade, and course hub\n",[24,1254,1255],{},[27,1256,1257],{},"All necessary items will be linked on Canvas",[27,1259,1260],{},"Discord is the preferred quick communication channel",[27,1262,1263],{},"QuackBot connects your Discord account to the correct course role",[27,1265,1266],{},"Good course communication keeps help requests specific and protects private information",{"title":148,"searchDepth":754,"depth":754,"links":1268},[1269,1270,1271,1272,1273,1274,1275,1276,1280,1281,1282],{"id":814,"depth":754,"text":815},{"id":848,"depth":754,"text":806},{"id":885,"depth":754,"text":889},{"id":933,"depth":754,"text":936},{"id":982,"depth":754,"text":985},{"id":1030,"depth":754,"text":1033},{"id":1063,"depth":754,"text":1066},{"id":1128,"depth":754,"text":1129,"children":1277},[1278],{"id":1146,"depth":1279,"text":1147},3,{"id":1166,"depth":754,"text":1169},{"id":619,"depth":754,"text":622},{"id":717,"depth":754,"text":720},"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",{},"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",{"title":806,"description":1283},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[1294,1295,1296,1297],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":1304,"title":1305,"audience":6,"body":1306,"contentType":775,"course":776,"description":2351,"estimateBasis":2352,"estimatedDiscussionMinutes":1285,"estimatedLiveMinutes":2353,"estimatedTotalMinutes":781,"extension":782,"meta":2354,"module":784,"navigation":785,"order":1285,"path":2355,"promptAssist":788,"seo":2356,"status":790,"stem":2357,"tags":2358,"videoDuration":2362,"videoId":2363,"videoLink":2364,"videoTitle":1305,"week":784,"__hash__":2365},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":1307,"toc":2317},[1308,1366,1401,1431,1493,1560,1611,1637,1654,1692,1720,1741,1776,1798,1870,1893,1938,2001,2053,2081,2101,2130,2168,2198,2208,2271],[11,1309,1311,1315],{"id":1310,"level":14},"why-cli-first",[16,1312,1314],{"id":1313},"why-cli-comes-first","Why CLI Comes First",[24,1316,1317,1325,1333,1347,1355],{},[27,1318,1319,1320],{},"Common language for setup and developer tools\n",[24,1321,1322],{},[27,1323,1324],{},"Git, servers, package installs, deployment logs",[27,1326,1327,1328],{},"Works when there is no full desktop\n",[24,1329,1330],{},[27,1331,1332],{},"SSH, Ubuntu Server, minimal system access",[27,1334,1335,1336],{},"Direct check of what the computer sees\n",[24,1337,1338,1341,1344],{},[27,1339,1340],{},"Current folder",[27,1342,1343],{},"Files and permissions",[27,1345,1346],{},"Command output",[27,1348,1349,1350],{},"Repeatable steps beat guessing through menus\n",[24,1351,1352],{},[27,1353,1354],{},"Run a command, read output, adjust",[27,1356,1357,1358],{},"Location still matters\n",[24,1359,1360,1363],{},[27,1361,1362],{},"Wrong folder can make correct commands fail",[27,1364,1365],{},"Or create files in the wrong place",[11,1367,1369,1372,1375],{"id":1368,"level":14},"goal",[16,1370,1371],{"id":1368},"Goal",[20,1373,1374],{},"Build the command-line habits that make setup work predictable:",[24,1376,1377,1380,1383,1395,1398],{},[27,1378,1379],{},"Know what folder the terminal is using",[27,1381,1382],{},"Read file and folder lists before moving",[27,1384,1385,1386,731,1389,734,1392],{},"Recognize common flags like ",[31,1387,1388],{},"-a",[31,1390,1391],{},"-r",[31,1393,1394],{},"-l",[27,1396,1397],{},"Make small file changes and verify them",[27,1399,1400],{},"Stop safely when output does not match the lesson",[11,1402,1403,1405,1408,1428],{"id":107,"level":14},[16,1404,110],{"id":107},[20,1406,1407],{},"Run these commands on your host computer",[24,1409,1410,1422,1425],{},[27,1411,1412,1413],{},"Windows: Git Bash",[24,1414,1415],{},[27,1416,1417,1418],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[694,1419,1421],{"href":1420},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fview\u002Fslides#step-1-install-git-on-windows","Install Git On Windows",[27,1423,1424],{},"Apple macOS: Terminal",[27,1426,1427],{},"Linux: Terminal",[20,1429,1430],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1432,1434,1438],{"id":1433,"level":14},"working-directory",[16,1435,1437],{"id":1436},"the-main-idea","The Main Idea",[24,1439,1440,1451,1462,1485],{},[27,1441,1442,1443],{},"Terminal commands run from one folder at a time\n",[24,1444,1445],{},[27,1446,1447,1448],{},"That folder is the ",[908,1449,1450],{},"working directory",[27,1452,1453,1456,1457],{},[31,1454,1455],{},"pwd",": print working directory\n",[24,1458,1459],{},[27,1460,1461],{},"Shows the full path to the folder your terminal is using",[27,1463,1464,1465],{},"Fresh terminal usually starts in your home folder\n",[24,1466,1467,1473,1479],{},[27,1468,1469,1470],{},"Windows Git Bash: ",[31,1471,1472],{},"\u002Fc\u002FUsers\u002Fyour-username",[27,1474,1475,1476],{},"Apple macOS: ",[31,1477,1478],{},"\u002FUsers\u002Fyour-username",[27,1480,1481,1482],{},"Linux: ",[31,1483,1484],{},"\u002Fhome\u002Fyour-username",[27,1486,1487,1488],{},"Commands from this lesson start from the working directory\n",[24,1489,1490],{},[27,1491,1492],{},"Unless you give a different path",[11,1494,1496,1499,1502,1554],{"id":1495,"level":14},"paths-relative-and-absolute",[16,1497,1498],{"id":1495},"Paths: Relative And Absolute",[20,1500,1501],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[24,1503,1504,1510,1516,1522,1548],{},[27,1505,1506,1507],{},"Relative path: starts from the working directory, like ",[31,1508,1509],{},"public\u002Findex.php",[27,1511,1512,1513],{},"Absolute path: starts from the system root, like ",[31,1514,1515],{},"\u002Fhome\u002Fstudent\u002Fproject",[27,1517,1518,1521],{},[31,1519,1520],{},"."," means the current folder",[27,1523,1524,1527,1528],{},[31,1525,1526],{},".."," means the parent folder\n",[24,1529,1530,1536,1542],{},[27,1531,1532,1535],{},[31,1533,1534],{},"..\u002F.."," goes up two folders",[27,1537,1538,1539],{},"Example: ",[31,1540,1541],{},"cd ..\u002F..",[27,1543,1544,1547],{},[31,1545,1546],{},"..."," is not a shortcut",[27,1549,1550,1553],{},[31,1551,1552],{},"~"," means your home folder",[20,1555,1556,1557,1559],{},"If a command affects the wrong place, check ",[31,1558,1455],{}," first, then check the path you typed",[11,1561,1563,1566,1569,1588,1591],{"id":1562,"level":14},"flags-options-and-arguments",[16,1564,1565],{"id":1562},"Flags, Options, And Arguments",[20,1567,1568],{},"Commands usually follow this shape:",[24,1570,1571,1577,1582],{},[27,1572,1573,1574],{},"Command: what to do, like ",[31,1575,1576],{},"ls",[27,1578,1579,1580],{},"Flag or option: how to do it, like ",[31,1581,1388],{},[27,1583,1584,1585],{},"Argument: what to do it to, like ",[31,1586,1587],{},"public_html",[20,1589,1590],{},"Examples:",[24,1592,1593,1599,1605],{},[27,1594,1595,1598],{},[31,1596,1597],{},"ls -a"," shows hidden files",[27,1600,1601,1604],{},[31,1602,1603],{},"cp -r folder backup-folder"," copies a folder",[27,1606,1607,1610],{},[31,1608,1609],{},"nano -l file.txt"," opens with line numbers",[11,1612,1614,1618,1621,1632],{"id":1613,"level":14},"practice-loop",[16,1615,1617],{"id":1616},"practice-1-location-and-paths","Practice 1: Location And Paths",[20,1619,1620],{},"For each command, use the same pattern:",[487,1622,1623,1626,1629],{},[27,1624,1625],{},"Run one command",[27,1627,1628],{},"Read the output",[27,1630,1631],{},"Confirm the folder or file changed the way you expected",[24,1633,1634],{},[27,1635,1636],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1638,1640,1643,1645,1648,1651],{"id":1639,"level":886},"step-1-confirm-where-you-are",[16,1641,1642],{"id":1639},"Step 1: Confirm Where You Are",[20,1644,151],{},[115,1646],{"language":118,"src":1647},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[20,1649,1650],{},"Expected result: a folder path",[20,1652,1653],{},"If you see a path, the terminal is working and you know your current location",[11,1655,1657,1660,1662,1665,1668,1671,1674],{"id":1656,"level":886},"step-2-list-files",[16,1658,1659],{"id":1656},"Step 2: List Files",[20,1661,151],{},[115,1663],{"language":118,"src":1664},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[20,1666,1667],{},"Expected result: file and folder names from your current location",[20,1669,1670],{},"For hidden files and details too, run:",[115,1672],{"language":118,"src":1673},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[24,1675,1676,1681,1686],{},[27,1677,1678,1680],{},[31,1679,1388],{}," includes hidden files",[27,1682,1683,1685],{},[31,1684,1394],{}," uses a long listing",[27,1687,1688,1691],{},[31,1689,1690],{},"-la"," combines both",[11,1693,1695,1698,1701,1704,1711,1717],{"id":1694,"level":886},"step-3-change-folders",[16,1696,1697],{"id":1694},"Step 3: Change Folders",[20,1699,1700],{},"Start from your home folder, then move up and back",[115,1702],{"language":118,"src":1703},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[20,1705,1706,1707,1710],{},"This avoids assuming your computer has a specific folder like ",[31,1708,1709],{},"Documents"," in the current location",[20,1712,1713,1714,1716],{},"When you move into a named folder later, run ",[31,1715,1576],{}," first and pick a folder that actually appears in the list",[20,1718,1719],{},"If a path has spaces, wrap it in quotes",[11,1721,1723,1727,1729,1732],{"id":1722,"level":886},"step-4-create-practice-folder",[16,1724,1726],{"id":1725},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[20,1728,151],{},[115,1730],{"language":118,"src":1731},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[20,1733,1734,1735,1737,1738],{},"Expected result: ",[31,1736,1455],{}," ends with ",[31,1739,1740],{},"cli-practice",[11,1742,1744,1748,1750,1753,1756],{"id":1743,"level":886},"step-5-create-and-read-file",[16,1745,1747],{"id":1746},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[20,1749,151],{},[115,1751],{"language":118,"src":1752},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[20,1754,1755],{},"What this command does:",[24,1757,1758,1764,1770],{},[27,1759,1760,1763],{},[31,1761,1762],{},"echo"," prepares text for the terminal",[27,1765,1766,1769],{},[31,1767,1768],{},">"," redirects that text into a file instead of printing it on screen",[27,1771,1772,1775],{},[31,1773,1774],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,1777,1779,1783,1786,1789,1795],{"id":1778,"level":886},"step-5-read-file-back",[658,1780,1782],{"id":1781},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[20,1784,1785],{},"Then read it back:",[115,1787],{"language":118,"src":1788},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[20,1790,1791,1794],{},[31,1792,1793],{},"cat"," prints file contents in the terminal",[20,1796,1797],{},"Expected result: the terminal prints the text you wrote",[11,1799,1801,1805,1807,1816,1819,1845,1848],{"id":1800,"level":14},"file-management-loop",[16,1802,1804],{"id":1803},"practice-2-file-management","Practice 2: File Management",[20,1806,1620],{},[487,1808,1809,1811,1813],{},[27,1810,1625],{},[27,1812,1628],{},[27,1814,1815],{},"Confirm the file changed the way you expected",[20,1817,1818],{},"Commands in this practice:",[24,1820,1821,1827,1833,1839],{},[27,1822,1823,1826],{},[31,1824,1825],{},"touch"," creates an empty file",[27,1828,1829,1832],{},[31,1830,1831],{},"cp"," copies a file or folder",[27,1834,1835,1838],{},[31,1836,1837],{},"mv"," moves or renames",[27,1840,1841,1844],{},[31,1842,1843],{},"rm"," deletes",[20,1846,1847],{},"Important flags:",[24,1849,1850,1856,1862,1868],{},[27,1851,1852,1855],{},[31,1853,1854],{},"cp -r"," copies folders",[27,1857,1858,1861],{},[31,1859,1860],{},"rm -r"," deletes folders",[27,1863,1864,1867],{},[31,1865,1866],{},"rm -f"," forces deletion",[27,1869,1636],{},[11,1871,1873,1877,1879,1882,1887],{"id":1872,"level":886},"practice-2-step-1-create-empty-file",[16,1874,1876],{"id":1875},"step-1-create-an-empty-file","Step 1: Create An Empty File",[20,1878,151],{},[115,1880],{"language":118,"src":1881},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[20,1883,1884,1886],{},[31,1885,1825],{}," creates an empty file, or updates the timestamp if the file already exists",[20,1888,1734,1889,1892],{},[31,1890,1891],{},"practice-empty.txt"," appears in the folder list",[11,1894,1896,1900,1902,1905,1908,1914,1927],{"id":1895,"level":886},"practice-2-step-2-copy-rename-and-delete",[16,1897,1899],{"id":1898},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[20,1901,151],{},[115,1903],{"language":118,"src":1904},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[20,1906,1907],{},"Expected result: the backup is copied, renamed, then removed",[20,1909,1910,1911,1913],{},"Use ",[31,1912,1843],{}," carefully. Deleting from the terminal usually skips the recycle bin",[24,1915,1916,1921],{},[27,1917,1918,1920],{},[31,1919,1391],{},": recursive, includes folders and everything inside them",[27,1922,1923,1926],{},[31,1924,1925],{},"-f",": force, skips many confirmation prompts",[1928,1929,1931],"alert",{"color":1930},"red",[20,1932,1933,1934,1937],{},"Never run ",[31,1935,1936],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,1939,1941,1945,1948,1966,1971,1976,1996],{"id":1940,"level":14},"terminal-editors",[16,1942,1944],{"id":1943},"practice-3-terminal-editors","Practice 3: Terminal Editors",[20,1946,1947],{},"Sometimes you need to edit a file from a terminal",[24,1949,1950,1956],{},[27,1951,1952,1955],{},[31,1953,1954],{},"nano"," is beginner-friendly",[27,1957,1958,1961,1962,1965],{},[31,1959,1960],{},"vi"," or ",[31,1963,1964],{},"vim"," is common on servers but has a learning curve",[20,1967,1910,1968,1970],{},[31,1969,1954],{}," for this course unless a lesson says otherwise",[20,1972,1910,1973,1975],{},[31,1974,1609],{}," when line numbers would help",[20,1977,1978,1979,1961,1981,1983,1984,1987,1988,1991,1992,1995],{},"If you accidentally open ",[31,1980,1960],{},[31,1982,1964],{},", press ",[31,1985,1986],{},"Esc",", type ",[31,1989,1990],{},":q",", and press ",[31,1993,1994],{},"Enter"," to exit without saving",[24,1997,1998],{},[27,1999,2000],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,2002,2004,2009,2011,2014,2019,2041],{"id":2003,"level":886},"edit-with-nano",[16,2005,2006,2007],{"id":2003},"Edit With ",[31,2008,1954],{},[20,2010,151],{},[115,2012],{"language":118,"src":2013},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[20,2015,1085,2016,2018],{},[31,2017,1954],{},":",[24,2020,2021,2024,2031,2035],{},[27,2022,2023],{},"Type a short note",[27,2025,2026,2027,2030],{},"Press ",[31,2028,2029],{},"Ctrl+O"," to save",[27,2032,2026,2033],{},[31,2034,1994],{},[27,2036,2026,2037,2040],{},[31,2038,2039],{},"Ctrl+X"," to exit",[20,2042,2043,2044,2046,2047,1987,2049,1991,2051],{},"If you open ",[31,2045,1960],{}," by mistake, press ",[31,2048,1986],{},[31,2050,1990],{},[31,2052,1994],{},[11,2054,2056,2062,2067,2070,2073,2076],{"id":2055,"level":14},"sudo-and-permission-boundaries",[16,2057,2058,2061],{"id":2055},[31,2059,2060],{},"sudo"," And Permission Boundaries",[20,2063,2064,2066],{},[31,2065,2060],{}," runs a command with elevated permissions",[20,2068,2069],{},"Use it only when a setup lesson explicitly says to use it",[20,2071,2072],{},"Example:",[115,2074],{"language":118,"src":2075},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[24,2077,2078],{},[27,2079,2080],{},"See the slide below for supporting examples and follow-up details",[11,2082,2084,2089,2095],{"id":2083,"level":886},"sudo-by-operating-system",[658,2085,2086,2088],{"id":2083},[31,2087,2060],{}," By Operating System",[20,2090,2091,2092,2094],{},"On Linux and macOS, ",[31,2093,2060],{}," is common for package installation and service management",[20,2096,2097,2098,2100],{},"Modern Windows also has a native ",[31,2099,2060],{}," 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,2102,2104,2107,2110,2121],{"id":2103,"level":14},"quick-safety-routine",[16,2105,2106],{"id":2103},"Quick Safety Routine",[20,2108,2109],{},"Before a command changes files, ask:",[24,2111,2112,2115,2118],{},[27,2113,2114],{},"What folder am I in?",[27,2116,2117],{},"Do I see the files I expect?",[27,2119,2120],{},"Am I about to change the right folder?",[20,2122,2123,2124,2126,2127],{},"If one answer is unclear, stop and run ",[31,2125,1455],{}," plus ",[31,2128,2129],{},"ls -la",[11,2131,2132,2134],{"id":576,"level":14},[16,2133,579],{"id":576},[24,2135,2136,2152,2158,2166],{},[27,2137,2138,2141,2142,2144,2145,2147,2148,2151],{},[31,2139,2140],{},"No such file or directory",": run ",[31,2143,1455],{},", then ",[31,2146,1576],{},", then try ",[31,2149,2150],{},"cd"," again",[27,2153,2154,2155,2157],{},"Command affected the wrong folder: check ",[31,2156,1455],{}," before continuing",[27,2159,2160,2162,2163,2165],{},[31,2161,1793],{}," cannot find the file: run ",[31,2164,2129],{}," and check the exact filename",[27,2167,2080],{},[11,2169,2171,2175],{"id":2170,"level":886},"common-mistakes-recovery",[658,2172,2174],{"id":2173},"recovery-checks","Recovery Checks",[24,2176,2177,2180,2186,2192],{},[27,2178,2179],{},"Spaces in a path: wrap the path in quotes",[27,2181,2182,2183],{},"Command keeps running: press ",[31,2184,2185],{},"Ctrl+C",[27,2187,2188,2189],{},"Permission denied: move back home with ",[31,2190,2191],{},"cd ~",[27,2193,2194,2195,2197],{},"Wrong ",[31,2196,1843],{},": stop and ask before doing more work",[11,2199,2200,2202,2205],{"id":619,"level":14},[16,2201,622],{"id":619},[20,2203,2204],{},"You are ready for the next setup lesson when these commands make sense:",[115,2206],{"language":118,"src":2207},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,2209,2210,2212],{"id":648,"level":14},[16,2211,652],{"id":651},[141,2213,2214,2244],{"gap":143,"left-width":144,"right-width":144},[146,2215,2216,2218,2224,2233],{"v-slot:left":148},[658,2217,661],{"id":660},[20,2219,2220,2223],{},[908,2221,2222],{},"Working directory"," - The folder where the next terminal command runs",[20,2225,2226,2229,2230],{},[908,2227,2228],{},"Path"," - A file or folder location, such as ",[31,2231,2232],{},"public_html\u002Findex.php",[20,2234,2235,2238,2239,2241,2242],{},[908,2236,2237],{},"Flag"," - An extra command option, such as ",[31,2240,1690],{}," in ",[31,2243,2129],{},[146,2245,2246,2248],{"v-slot:right":148},[658,2247,687],{"id":648},[24,2249,2250,2257,2264],{},[27,2251,2252],{},[694,2253,2256],{"href":2254,"rel":2255},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[698],"Ubuntu Tutorial: The Linux Command Line For Beginners",[27,2258,2259],{},[694,2260,2263],{"href":2261,"rel":2262},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[698],"GNU Coreutils Manual",[27,2265,2266],{},[694,2267,2270],{"href":2268,"rel":2269},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[698],"MDN: Command Line Crash Course",[11,2272,2273,2275,2277],{"id":717,"level":14},[16,2274,720],{"id":717},[20,2276,723],{},[24,2278,2279,2284,2289,2300,2314],{},[27,2280,1910,2281,2283],{},[31,2282,1455],{}," to check where commands will run",[27,2285,1910,2286,2288],{},[31,2287,2129],{}," to inspect the current folder",[27,2290,1910,2291,731,2293,731,2295,734,2297,2299],{},[31,2292,2150],{},[31,2294,1520],{},[31,2296,1526],{},[31,2298,1552],{}," to move intentionally",[27,2301,2302,2303,731,2305,731,2307,731,2309,734,2311,2313],{},"Use file commands such as ",[31,2304,1825],{},[31,2306,1831],{},[31,2308,1837],{},[31,2310,1843],{},[31,2312,1954],{}," carefully",[27,2315,2316],{},"Stop and check location when output does not match the lesson",{"title":148,"searchDepth":754,"depth":754,"links":2318},[2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2333,2334,2335,2336,2337,2339,2344,2345,2348,2349,2350],{"id":1313,"depth":754,"text":1314},{"id":1368,"depth":754,"text":1371},{"id":107,"depth":754,"text":110},{"id":1436,"depth":754,"text":1437},{"id":1495,"depth":754,"text":1498},{"id":1562,"depth":754,"text":1565},{"id":1616,"depth":754,"text":1617},{"id":1639,"depth":754,"text":1642},{"id":1656,"depth":754,"text":1659},{"id":1694,"depth":754,"text":1697},{"id":1725,"depth":754,"text":1726},{"id":1746,"depth":754,"text":1747,"children":2331},[2332],{"id":1781,"depth":1279,"text":1782},{"id":1803,"depth":754,"text":1804},{"id":1875,"depth":754,"text":1876},{"id":1898,"depth":754,"text":1899},{"id":1943,"depth":754,"text":1944},{"id":2003,"depth":754,"text":2338},"Edit With nano",{"id":2055,"depth":754,"text":2340,"children":2341},"sudo And Permission Boundaries",[2342],{"id":2083,"depth":1279,"text":2343},"sudo By Operating System",{"id":2103,"depth":754,"text":2106},{"id":576,"depth":754,"text":579,"children":2346},[2347],{"id":2173,"depth":1279,"text":2174},{"id":619,"depth":754,"text":622},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":1305,"description":2351},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[2359,2360,2361],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":2367,"title":2368,"audience":6,"body":2369,"contentType":775,"course":776,"description":3240,"estimateBasis":3241,"estimatedDiscussionMinutes":1285,"estimatedLiveMinutes":3242,"estimatedTotalMinutes":2353,"extension":782,"meta":3243,"module":784,"navigation":785,"order":1286,"path":3244,"promptAssist":788,"seo":3245,"status":790,"stem":3246,"tags":3247,"videoDuration":3248,"videoId":3249,"videoLink":3250,"videoTitle":2368,"week":784,"__hash__":3251},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":2370,"toc":3210},[2371,2394,2423,2451,2489,2520,2551,2585,2614,2644,2681,2684,2714,2745,2774,2824,2842,2859,2879,2904,2935,2953,2994,3039,3121,3181],[11,2372,2373,2375],{"id":1368,"level":14},[16,2374,1371],{"id":1368},[24,2376,2377,2380,2383],{},[27,2378,2379],{},"Install Git",[27,2381,2382],{},"Choose one terminal for your operating system",[27,2384,2385,2386,731,2389,734,2391,2393],{},"Confirm ",[31,2387,2388],{},"git --version",[31,2390,1455],{},[31,2392,2129],{}," work before GitHub setup",[11,2395,2397,2401],{"id":2396,"level":14},"terminal-choice-by-os",[16,2398,2400],{"id":2399},"terminal-choices","Terminal Choices",[24,2402,2403,2406,2409,2412,2414,2417,2420],{},[27,2404,2405],{},"Pick the terminal for your operating system",[27,2407,2408],{},"Use that same terminal for this lesson path",[27,2410,2411],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[27,2413,1412],{},[27,2415,2416],{},"Apple macOS: Terminal, with iTerm2 optional",[27,2418,2419],{},"Linux: Terminal, with Tilix optional",[27,2421,2422],{},"These operating system notes are alternatives, not a sequence",[11,2424,2426,2430,2448],{"id":2425,"level":14},"step-1-install-git-on-windows",[16,2427,2429],{"id":2428},"windows-path-git-bash","Windows Path: Git Bash",[487,2431,2432,2439,2442,2445],{},[27,2433,2434,2435],{},"Go to ",[694,2436,2437],{"href":2437,"rel":2438},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[698],[27,2440,2441],{},"Download and run the Git for Windows installer",[27,2443,2444],{},"Open Git Bash from the Start menu",[27,2446,2447],{},"Use Git Bash whenever this course says to use the terminal",[20,2449,2450],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,2452,2454,2457],{"id":2453,"level":886},"windows-installer-components",[658,2455,2456],{"id":2453},"Windows Installer: Components",[141,2458,2462,2470],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},"1.4fr","0.9fr","never",[146,2463,2464],{"v-slot:left":148},[20,2465,2466],{},[926,2467],{"alt":2468,"src":2469,"variant":930},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[146,2471,2472],{"v-slot:right":148},[24,2473,2474,2477,2483],{},[27,2475,2476],{},"Recommended to have these components selected",[27,2478,2479,2480],{},"Keep ",[31,2481,2482],{},"Git Bash Here",[27,2484,2485,2486],{},"Continue with ",[31,2487,2488],{},"Next",[11,2490,2492,2495],{"id":2491,"level":886},"windows-installer-default-editor",[658,2493,2494],{"id":2491},"Windows Installer: Default Editor",[141,2496,2497,2505],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2498,2499],{"v-slot:left":148},[20,2500,2501],{},[926,2502],{"alt":2503,"src":2504,"variant":930},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[146,2506,2507],{"v-slot:right":148},[24,2508,2509,2512,2517],{},[27,2510,2511],{},"Choose the editor you are comfortable with",[27,2513,2514,2516],{},[31,2515,1954],{}," or VS Code is friendlier than Vim for most beginners",[27,2518,2519],{},"This setting affects Git messages if Git opens an editor",[11,2521,2523,2526],{"id":2522,"level":886},"windows-installer-branch-name",[658,2524,2525],{"id":2522},"Windows Installer: Branch Name",[141,2527,2528,2536],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2529,2530],{"v-slot:left":148},[20,2531,2532],{},[926,2533],{"alt":2534,"src":2535,"variant":930},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[146,2537,2538],{"v-slot:right":148},[24,2539,2540,2545,2548],{},[27,2541,2542,2543],{},"Select the option that uses ",[31,2544,67],{},[27,2546,2547],{},"Course repositories will tell you which branch to use later",[27,2549,2550],{},"Do not create custom branch names here",[11,2552,2554,2557],{"id":2553,"level":886},"windows-installer-path",[658,2555,2556],{"id":2553},"Windows Installer: PATH",[141,2558,2559,2567],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2560,2561],{"v-slot:left":148},[20,2562,2563],{},[926,2564],{"alt":2565,"src":2566,"variant":930},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[146,2568,2569],{"v-slot:right":148},[24,2570,2571,2574,2579,2582],{},[27,2572,2573],{},"Select the recommended PATH option",[27,2575,2576,2577],{},"This lets Git Bash and common tools find ",[31,2578,793],{},[27,2580,2581],{},"Avoid options that say Git Bash only",[27,2583,2584],{},"The third option can be used if you understand the consequences",[11,2586,2588,2591],{"id":2587,"level":886},"windows-installer-ssh",[658,2589,2590],{"id":2587},"Windows Installer: SSH",[141,2592,2593,2601],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2594,2595],{"v-slot:left":148},[20,2596,2597],{},[926,2598],{"alt":2599,"src":2600,"variant":930},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[146,2602,2603],{"v-slot:right":148},[24,2604,2605,2608,2611],{},[27,2606,2607],{},"Use the bundled OpenSSH option",[27,2609,2610],{},"This keeps Git Bash SSH behavior predictable",[27,2612,2613],{},"SSH setup happens in the next lesson",[11,2615,2617,2621],{"id":2616,"level":886},"windows-installer-openssl",[658,2618,2620],{"id":2619},"windows-installer-https","Windows Installer: HTTPS",[141,2622,2623,2631],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2624,2625],{"v-slot:left":148},[20,2626,2627],{},[926,2628],{"alt":2629,"src":2630,"variant":930},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[146,2632,2633],{"v-slot:right":148},[24,2634,2635,2638,2641],{},[27,2636,2637],{},"Keep the OpenSSL option",[27,2639,2640],{},"This is the normal Git for Windows choice",[27,2642,2643],{},"It supports secure GitHub connections",[11,2645,2647,2651],{"id":2646,"level":886},"windows-installer-checkout-style",[658,2648,2650],{"id":2649},"windows-installer-line-endings","Windows Installer: Line Endings",[141,2652,2653,2661],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2654,2655],{"v-slot:left":148},[20,2656,2657],{},[926,2658],{"alt":2659,"src":2660,"variant":930},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[146,2662,2663,2674],{"v-slot:right":148},[24,2664,2665,2668,2671],{},[27,2666,2667],{},"Keep the default line-ending option",[27,2669,2670],{},"Git handles Windows and Linux line endings for you",[27,2672,2673],{},"Do not change this unless a lesson says to",[2675,2676,2678],"admonition",{"type":2677},"note",[20,2679,2680],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[20,2682,2683],{},"::\n::",[11,2685,2687,2691],{"id":2686,"level":886},"windows-installer-mintty",[658,2688,2690],{"id":2689},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[141,2692,2693,2701],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2694,2695],{"v-slot:left":148},[20,2696,2697],{},[926,2698],{"alt":2699,"src":2700,"variant":930},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[146,2702,2703],{"v-slot:right":148},[24,2704,2705,2708,2711],{},[27,2706,2707],{},"Keep MinTTY selected",[27,2709,2710],{},"This is the normal Git Bash window",[27,2712,2713],{},"Course screenshots will assume this terminal style",[11,2715,2717,2721],{"id":2716,"level":886},"windows-installer-fast-forward",[658,2718,2720],{"id":2719},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[141,2722,2723,2731],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2724,2725],{"v-slot:left":148},[20,2726,2727],{},[926,2728],{"alt":2729,"src":2730,"variant":930},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[146,2732,2733],{"v-slot:right":148},[24,2734,2735,2742],{},[27,2736,2737,2738,2741],{},"Keep the default ",[31,2739,2740],{},"git pull"," behavior",[27,2743,2744],{},"Later lessons explain pull, merge, and conflicts",[11,2746,2748,2751],{"id":2747,"level":886},"windows-installer-credential-manager",[658,2749,2750],{"id":2747},"Windows Installer: Credential Manager",[141,2752,2753,2761],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2754,2755],{"v-slot:left":148},[20,2756,2757],{},[926,2758],{"alt":2759,"src":2760,"variant":930},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[146,2762,2763],{"v-slot:right":148},[24,2764,2765,2768,2771],{},[27,2766,2767],{},"Keep Git Credential Manager enabled",[27,2769,2770],{},"It helps with browser-based GitHub sign-in",[27,2772,2773],{},"This course still uses SSH for repo pushes",[11,2775,2777,2780],{"id":2776,"level":886},"windows-installer-extra-options",[658,2778,2779],{"id":2776},"Windows Installer: Extra Options",[141,2781,2782,2790],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,2783,2784],{"v-slot:left":148},[20,2785,2786],{},[926,2787],{"alt":2788,"src":2789,"variant":930},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[146,2791,2792],{"v-slot:right":148},[24,2793,2794,2802,2813,2821],{},[27,2795,2796,2797],{},"Enable file system caching\n",[24,2798,2799],{},[27,2800,2801],{},"Improves Git performance on Windows",[27,2803,2804,2805],{},"Enable symbolic links if available\n",[24,2806,2807,2810],{},[27,2808,2809],{},"Helps Git handle link-like files correctly",[27,2811,2812],{},"May require Windows Developer Mode or admin rights",[27,2814,2815,2816],{},"Skip experimental options\n",[24,2817,2818],{},[27,2819,2820],{},"They can change behavior between Git versions",[27,2822,2823],{},"Finish the installer",[11,2825,2827,2831],{"id":2826,"level":886},"step-1-open-git-bash-on-windows",[658,2828,2830],{"id":2829},"open-git-bash","Open Git Bash",[24,2832,2833,2836,2839],{},[27,2834,2835],{},"Start menu -> Git Bash",[27,2837,2838],{},"Pin it if that helps you find the same terminal later",[27,2840,2841],{},"Run the checks in the next slides from Git Bash",[11,2843,2845,2848],{"id":2844,"level":886},"windows-terminal-habit",[658,2846,2847],{"id":2844},"Windows Terminal Habit",[24,2849,2850,2853,2856],{},[27,2851,2852],{},"Use Git Bash for course commands on Windows",[27,2854,2855],{},"If another terminal opens by accident, close it and open Git Bash",[27,2857,2858],{},"Staying in one terminal makes setup problems easier to diagnose",[11,2860,2862,2865],{"id":2861,"level":14},"macos-path-terminal",[16,2863,2864],{"id":2861},"macOS Path: Terminal",[24,2866,2867,2870,2873,2876],{},[27,2868,2869],{},"Built-in Terminal is fully supported",[27,2871,2872],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[27,2874,2875],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[27,2877,2878],{},"See the slide below for the optional modern terminal install path",[11,2880,2882,2886],{"id":2881,"level":886},"macos-optional-iterm2-install",[658,2883,2885],{"id":2884},"optional-iterm2-install","Optional iTerm2 Install",[24,2887,2888,2895,2898,2901],{},[27,2889,2890,2891],{},"Download the stable release from ",[694,2892,2893],{"href":2893,"rel":2894},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[698],[27,2896,2897],{},"Move iTerm2 to Applications",[27,2899,2900],{},"Open iTerm2 and run the same checks as Terminal",[27,2902,2903],{},"Use Terminal or iTerm2 consistently for course commands",[11,2905,2907,2910,2924,2927,2930],{"id":2906,"level":14},"linux-path-terminal",[16,2908,2909],{"id":2906},"Linux Path: Terminal",[24,2911,2912,2915,2918],{},[27,2913,2914],{},"Open the built-in Terminal app",[27,2916,2917],{},"Git is often installed already",[27,2919,2920,2921,2923],{},"If ",[31,2922,2388],{}," fails, use your distribution package manager",[20,2925,2926],{},"For Ubuntu:",[115,2928],{"language":118,"src":2929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[24,2931,2932],{},[27,2933,2934],{},"See the slide below for the optional split-pane terminal setup",[11,2936,2938,2942,2945,2947,2950],{"id":2937,"level":886},"linux-optional-tilix-install",[658,2939,2941],{"id":2940},"optional-tilix-install","Optional Tilix Install",[20,2943,2944],{},"Tilix is a Linux terminal with split panes and profiles",[20,2946,2926],{},[115,2948],{"language":118,"src":2949},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[20,2951,2952],{},"Use the built-in Terminal if optional installs add friction",[11,2954,2956,2960],{"id":2955,"level":14},"step-3-confirm-git-and-shell",[16,2957,2959],{"id":2958},"confirm-git-and-shell","Confirm Git And Shell",[141,2961,2964,2978],{"gap":143,"left-width":2962,"right-width":2963},"1.15fr","0.85fr",[146,2965,2966,2968,2971,2974],{"v-slot:left":148},[20,2967,151],{},[115,2969],{"language":118,"src":2970},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[20,2972,2973],{},"Expected output:",[115,2975],{"language":2976,"src":2977},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[146,2979,2980,2983],{"v-slot:right":148},[20,2981,2982],{},"This confirms:",[24,2984,2985,2988,2991],{},[27,2986,2987],{},"Git is installed",[27,2989,2990],{},"The terminal can find Git",[27,2992,2993],{},"Your shell matches later course commands",[11,2995,2997,3001],{"id":2996,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,2998,3000],{"id":2999},"check-location-before-git-commands","Check Location Before Git Commands",[141,3002,3004,3016],{"gap":143,"left-width":3003,"right-width":2460},"1.1fr",[146,3005,3006,3008,3011,3013],{"v-slot:left":148},[20,3007,151],{},[115,3009],{"language":118,"src":3010},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[20,3012,2973],{},[115,3014],{"language":2976,"src":3015},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[146,3017,3018,3021],{"v-slot:right":148},[20,3019,3020],{},"Use this before Git commands:",[24,3022,3023,3028,3033,3036],{},[27,3024,3025,3027],{},[31,3026,1455],{}," shows the current folder",[27,3029,3030,3032],{},[31,3031,2129],{}," shows what is inside it",[27,3034,3035],{},"If the folder is wrong, fix location first",[27,3037,3038],{},"Do not run Git commands while guessing",[11,3040,3041,3043],{"id":576,"level":14},[16,3042,579],{"id":576},[141,3044,3045,3087],{"gap":143,"left-width":144,"right-width":144},[146,3046,3047],{"v-slot:left":148},[24,3048,3049,3062,3079],{},[27,3050,3051,3054],{},[31,3052,3053],{},"git: command not found",[24,3055,3056,3059],{},[27,3057,3058],{},"Git is missing, or this terminal cannot find it",[27,3060,3061],{},"Close the terminal and reopen the correct one",[27,3063,3064,3067],{},[31,3065,3066],{},"not a git repository",[24,3068,3069,3072],{},[27,3070,3071],{},"The command ran outside a cloned repository",[27,3073,1910,3074,34,3076,3078],{},[31,3075,1455],{},[31,3077,2129],{},", then move to the repo folder",[27,3080,3081,3082],{},"Wrong terminal",[24,3083,3084],{},[27,3085,3086],{},"Windows users should switch back to Git Bash",[146,3088,3089,3092],{"v-slot:right":148},[27,3090,3091],{},"Too many terminals open",[487,3093,3094,3097,3107,3112,3118],{},[27,3095,3096],{},"Close extra terminal windows",[27,3098,3099,3100],{},"Open the correct terminal\n",[24,3101,3102,3104],{},[27,3103,1412],{},[27,3105,3106],{},"Apple macOS\u002FLinux: Terminal",[27,3108,3109,3110],{},"Run ",[31,3111,2388],{},[27,3113,3109,3114,34,3116],{},[31,3115,1455],{},[31,3117,2129],{},[27,3119,3120],{},"Continue only after the folder looks right",[11,3122,3123,3125],{"id":648,"level":14},[16,3124,652],{"id":651},[141,3126,3127,3149],{"gap":143,"left-width":144,"right-width":144},[146,3128,3129,3131,3137,3143],{"v-slot:left":148},[658,3130,661],{"id":660},[20,3132,3133,3136],{},[908,3134,3135],{},"Terminal"," - A text-based interface where you type commands to control your computer",[20,3138,3139,3142],{},[908,3140,3141],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[20,3144,3145,3148],{},[908,3146,3147],{},"Git"," - A tool for tracking changes in code files over time",[146,3150,3151,3153],{"v-slot:right":148},[658,3152,687],{"id":648},[24,3154,3155,3162,3168,3174],{},[27,3156,3157],{},[694,3158,3161],{"href":3159,"rel":3160},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[698],"Git Downloads",[27,3163,3164],{},[694,3165,3167],{"href":2437,"rel":3166},[698],"Git For Windows Install Page",[27,3169,3170],{},[694,3171,3173],{"href":2893,"rel":3172},[698],"iTerm2 Downloads",[27,3175,3176],{},[694,3177,3180],{"href":3178,"rel":3179},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[698],"Tilix",[11,3182,3183,3185,3188],{"id":717,"level":14},[16,3184,720],{"id":717},[20,3186,3187],{},"Before moving on, confirm you can:",[24,3189,3190,3193,3197,3204,3207],{},[27,3191,3192],{},"Open the correct terminal for your operating system",[27,3194,3109,3195],{},[31,3196,2388],{},[27,3198,1910,3199,34,3201,3203],{},[31,3200,1455],{},[31,3202,2129],{}," to check your location",[27,3205,3206],{},"Understand what terminal\u002FCLI refers to",[27,3208,3209],{},"Keep track of terminal instances",{"title":148,"searchDepth":754,"depth":754,"links":3211},[3212,3213,3214,3229,3232,3235,3236,3237,3238,3239],{"id":1368,"depth":754,"text":1371},{"id":2399,"depth":754,"text":2400},{"id":2428,"depth":754,"text":2429,"children":3215},[3216,3217,3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228],{"id":2453,"depth":1279,"text":2456},{"id":2491,"depth":1279,"text":2494},{"id":2522,"depth":1279,"text":2525},{"id":2553,"depth":1279,"text":2556},{"id":2587,"depth":1279,"text":2590},{"id":2619,"depth":1279,"text":2620},{"id":2649,"depth":1279,"text":2650},{"id":2689,"depth":1279,"text":2690},{"id":2719,"depth":1279,"text":2720},{"id":2747,"depth":1279,"text":2750},{"id":2776,"depth":1279,"text":2779},{"id":2829,"depth":1279,"text":2830},{"id":2844,"depth":1279,"text":2847},{"id":2861,"depth":754,"text":2864,"children":3230},[3231],{"id":2884,"depth":1279,"text":2885},{"id":2906,"depth":754,"text":2909,"children":3233},[3234],{"id":2940,"depth":1279,"text":2941},{"id":2958,"depth":754,"text":2959},{"id":2999,"depth":754,"text":3000},{"id":576,"depth":754,"text":579},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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":2368,"description":3240},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[793,2360,1297],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":3253,"title":3254,"audience":6,"body":3255,"contentType":775,"course":776,"description":4328,"estimateBasis":4329,"estimatedDiscussionMinutes":779,"estimatedLiveMinutes":786,"estimatedTotalMinutes":4330,"extension":782,"meta":4331,"module":784,"navigation":785,"order":1287,"path":4332,"promptAssist":788,"seo":4333,"status":790,"stem":4334,"tags":4335,"videoDuration":4339,"videoId":4340,"videoLink":4341,"videoTitle":4342,"week":784,"__hash__":4343},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":3256,"toc":4300},[3257,3283,3301,3326,3339,3365,3402,3479,3526,3593,3669,3711,3737,3769,3807,3852,3886,3955,3957,3960,3971,4043,4072,4106,4154,4200,4268],[11,3258,3260,3263],{"id":3259,"level":14},"goals",[16,3261,3262],{"id":3259},"Goals",[24,3264,3265,3268,3271,3274,3277,3280],{},[27,3266,3267],{},"Confirm Git works in the correct terminal",[27,3269,3270],{},"Sign in to GitHub with a school or personal account",[27,3272,3273],{},"Create or reuse an SSH key for GitHub",[27,3275,3276],{},"Add the public key to GitHub",[27,3278,3279],{},"Create and clone your course repository",[27,3281,3282],{},"Set Git identity inside the cloned repository",[11,3284,3286,3289,3298],{"id":3285,"level":14},"terminal-by-os",[16,3287,3288],{"id":3285},"Terminal By OS",[24,3290,3291,3293,3296],{},[27,3292,1412],{},[27,3294,3295],{},"Apple macOS: Terminal or iTerm2",[27,3297,1427],{},[20,3299,3300],{},"Run these commands on your own computer",[11,3302,3304,3307],{"id":3303,"level":14},"git-and-ssh-terms",[16,3305,3306],{"id":3303},"Git And SSH Terms",[24,3308,3309,3312,3320,3323],{},[27,3310,3311],{},"Git identity: name and email attached to commits in a repository",[27,3313,3314,3315],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[24,3316,3317],{},[27,3318,3319],{},"This is how we'll authenticate to GitHub",[27,3321,3322],{},"SSH agent: helper that keeps your private key available to Git commands",[27,3324,3325],{},"Clone: local folder connected to a GitHub repository",[11,3327,3329,3332,3336],{"id":3328,"level":14},"ssh-key-flow",[16,3330,3331],{"id":3328},"SSH Key Flow",[3333,3334],"mermaid",{"code":3335},"sequenceDiagram\n  participant Terminal\n  participant PrivateKey as Private key on your computer\n  participant GitHub as Public key in GitHub\n  Terminal->>PrivateKey: Load key with ssh-add\n  Terminal->>GitHub: Ask to authenticate\n  GitHub-->>Terminal: Confirm matching public key\n",[20,3337,3338],{},"GitHub receives only the public key. The private key stays on your computer",[11,3340,3342,3345],{"id":3341,"level":14},"step-1-check-git",[16,3343,3344],{"id":3341},"Step 1: Check Git",[141,3346,3347,3355],{"gap":143,"left-width":144,"right-width":144},[146,3348,3349,3351],{"v-slot:left":148},[20,3350,151],{},[115,3352],{"label":3353,"language":118,"src":3354},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[146,3356,3357,3359,3362],{"v-slot:right":148},[20,3358,2973],{},[115,3360],{"label":163,"language":2976,"src":3361},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[20,3363,3364],{},"A valid version means Git is installed and available in this terminal",[11,3366,3368,3372],{"id":3367,"level":14},"step-2-github-account",[16,3369,3371],{"id":3370},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[141,3373,3375,3394],{"gap":143,"left-width":144,"right-width":3374},"0.8fr",[146,3376,3377],{"v-slot:left":148},[24,3378,3379,3382,3385,3388,3391],{},[27,3380,3381],{},"Use an existing GitHub account or create one",[27,3383,3384],{},"School email recommended for course identity",[27,3386,3387],{},"Personal email is fine if you prefer it",[27,3389,3390],{},"Avoid work email so course access does not depend on an employer account",[27,3392,3393],{},"Confirm you can open GitHub Settings before continuing",[146,3395,3396],{"v-slot:right":148},[20,3397,3398],{},[926,3399],{"alt":3400,"src":3401,"variant":930},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3403,3405,3409],{"id":3404,"level":14},"step-2-create-repo",[16,3406,3408],{"id":3407},"step-3-create-course-repository","Step 3: Create Course Repository",[141,3410,3412,3471],{"gap":143,"left-width":3411,"right-width":2962},"0.95fr",[146,3413,3414,3417],{"v-slot:left":148},[20,3415,3416],{},"In GitHub:",[24,3418,3419,3424,3430,3436,3451,3457,3460,3468],{},[27,3420,951,3421],{},[31,3422,3423],{},"+",[27,3425,3426,3427],{},"Choose ",[31,3428,3429],{},"New repository",[27,3431,3432,3433],{},"Name it ",[31,3434,3435],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[27,3437,3438,3439,3442,3443,3446,3447,3450],{},"Semester code examples: ",[31,3440,3441],{},"S2026"," spring, ",[31,3444,3445],{},"M2026"," summer, ",[31,3448,3449],{},"F2026"," fall",[27,3452,3453,3454],{},"Set visibility to ",[31,3455,3456],{},"Private",[27,3458,3459],{},"Toggle \"Add README\"",[27,3461,3462,3463],{},"Do not toggle \"Add .gitignore\"",[24,3464,3465],{},[27,3466,3467],{},"A future lesson will discuss and add this important file",[27,3469,3470],{},"Do not add starter files unless instructed",[146,3472,3473],{"v-slot:right":148},[20,3474,3475],{},[926,3476],{"alt":3477,"src":3478,"variant":930},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3480,3482,3486,3512],{"id":3481,"level":14},"step-3-check-existing-key",[16,3483,3485],{"id":3484},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[141,3487,3488,3496],{"gap":143,"left-width":144,"right-width":144},[146,3489,3490,3492],{"v-slot:left":148},[20,3491,151],{},[115,3493],{"label":3494,"language":118,"src":3495},"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",[146,3497,3498,3500,3503],{"v-slot:right":148},[20,3499,160],{},[115,3501],{"label":163,"language":2976,"src":3502},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[20,3504,3505,3506,34,3509],{},"Look for a matching GitHub-specific pair such as ",[31,3507,3508],{},"github_key",[31,3510,3511],{},"github_key.pub",[20,3513,3514,3515,3518,3519,1961,3522,3525],{},"You can reuse an existing matching pair only if it is ",[908,3516,3517],{},"NOT"," a default key such as ",[31,3520,3521],{},"id_ed25519",[31,3523,3524],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3527,3529,3533,3535,3539,3541,3544],{"id":3528,"level":14},"step-4-create-key-if-needed",[16,3530,3532],{"id":3531},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[20,3534,151],{},[115,3536],{"label":3537,"language":118,"src":3538},"create-github-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-4-create-ssh-key-if-needed-05.sh",[20,3540,160],{},[115,3542],{"label":163,"language":2976,"src":3543},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[24,3545,3546,3572,3577,3582],{},[27,3547,3548,3549],{},"Command flags:\n",[24,3550,3551,3557,3563],{},[27,3552,3553,3556],{},[31,3554,3555],{},"-t"," chooses the key type",[27,3558,3559,3562],{},[31,3560,3561],{},"-C"," adds a comment label, usually your GitHub email",[27,3564,3565,3567,3568,3571],{},[31,3566,1925],{}," chooses the output file path (must include ",[31,3569,3570],{},"~\u002F.ssh\u002F"," followed by the file name)",[27,3573,3574,3576],{},[31,3575,3508],{}," is the private key file",[27,3578,3579,3581],{},[31,3580,3511],{}," is the public key file for GitHub",[27,3583,3584,3585],{},"Passphrase is optional unless your instructor requires one\n",[24,3586,3587,3590],{},[27,3588,3589],{},"Pro: protects the key if someone gets the file",[27,3591,3592],{},"Con: adds an unlock prompt when the key is used",[11,3594,3596,3600,3617,3649],{"id":3595,"level":14},"step-5-start-agent-and-add-key",[16,3597,3599],{"id":3598},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[141,3601,3602,3610],{"gap":143,"left-width":3003,"right-width":144},[146,3603,3604,3606],{"v-slot:left":148},[20,3605,151],{},[115,3607],{"label":3608,"language":118,"src":3609},"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",[146,3611,3612,3614],{"v-slot:right":148},[20,3613,160],{},[115,3615],{"label":163,"language":2976,"src":3616},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[24,3618,3619,3625,3646],{},[27,3620,3621,3624],{},[31,3622,3623],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[27,3626,3627,3628,3631,3632,3635],{},"If that fails, run ",[31,3629,3630],{},"exec ssh-agent bash",", then run ",[31,3633,3634],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[24,3636,3637],{},[27,3638,1910,3639,3642,3643,3645],{},[31,3640,3641],{},"~\u002F.ssh\u002Fgithub_key"," because ",[31,3644,1552],{}," avoids issues with spaces in home directory paths",[27,3647,3648],{},"Then verify the key is loaded",[141,3650,3651,3659],{"gap":143,"left-width":144,"right-width":144},[146,3652,3653,3655],{"v-slot:left":148},[20,3654,151],{},[115,3656],{"label":3657,"language":118,"src":3658},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[146,3660,3661,3663,3666],{"v-slot:right":148},[20,3662,2973],{},[115,3664],{"label":163,"language":2976,"src":3665},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[20,3667,3668],{},"One loaded key is enough for this lesson",[11,3670,3672,3676,3693],{"id":3671,"level":14},"step-6-copy-public-key",[16,3673,3675],{"id":3674},"step-7-copy-public-key","Step 7: Copy Public Key",[141,3677,3678,3686],{"gap":143,"left-width":144,"right-width":144},[146,3679,3680,3682],{"v-slot:left":148},[20,3681,151],{},[115,3683],{"label":3684,"language":118,"src":3685},"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",[146,3687,3688,3690],{"v-slot:right":148},[20,3689,160],{},[115,3691],{"label":163,"language":2976,"src":3692},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[24,3694,3695,3705],{},[27,3696,3697,3698,3701,3702,3704],{},"Copy the full line starting with ",[31,3699,3700],{},"ssh-ed25519"," and ending with the value you set with ",[31,3703,3561],{}," earlier",[27,3706,3707,3708,3710],{},"Do not copy ",[31,3709,3508],{},", which is the private key (never share the private key)",[11,3712,3714,3718],{"id":3713,"level":14},"step-7-add-key-to-github",[16,3715,3717],{"id":3716},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[24,3719,3720,3723,3728,3731,3734],{},[27,3721,3722],{},"In GitHub, open account settings",[27,3724,2434,3725],{},[31,3726,3727],{},"SSH and GPG keys",[27,3729,3730],{},"Add a new authentication key",[27,3732,3733],{},"Paste the public key from the previous step",[27,3735,3736],{},"See the slides below for the GitHub screens",[11,3738,3740,3744],{"id":3739,"level":886},"step-8-open-github-settings",[658,3741,3743],{"id":3742},"open-github-settings","Open GitHub Settings",[141,3745,3746,3754],{"gap":143,"left-width":3003,"right-width":2460,"stack":2461},[146,3747,3748],{"v-slot:left":148},[20,3749,3750],{},[926,3751],{"alt":3752,"src":3753,"variant":930},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[146,3755,3756],{"v-slot:right":148},[24,3757,3758,3761,3766],{},[27,3759,3760],{},"Click your GitHub profile photo",[27,3762,3426,3763],{},[31,3764,3765],{},"Settings",[27,3767,3768],{},"Use the account menu, not the repository settings",[11,3770,3772,3776],{"id":3771,"level":886},"step-8-open-ssh-keys-page",[658,3773,3775],{"id":3774},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[141,3777,3778,3786],{"gap":143,"left-width":3003,"right-width":2460,"stack":2461},[146,3779,3780],{"v-slot:left":148},[20,3781,3782],{},[926,3783],{"alt":3784,"src":3785,"variant":930},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[146,3787,3788],{"v-slot:right":148},[24,3789,3790,3797,3802],{},[27,3791,3792,3793,3796],{},"Find the ",[31,3794,3795],{},"Access"," section",[27,3798,3799,3800],{},"Open ",[31,3801,3727],{},[27,3803,3426,3804],{},[31,3805,3806],{},"New SSH key",[11,3808,3810,3814],{"id":3809,"level":886},"step-8-add-new-ssh-key",[658,3811,3813],{"id":3812},"add-new-ssh-key","Add New SSH Key",[141,3815,3817,3825],{"gap":143,"left-width":3816,"right-width":2963,"stack":2461},"1.35fr",[146,3818,3819],{"v-slot:left":148},[20,3820,3821],{},[926,3822],{"alt":3823,"src":3824,"variant":930},"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",[146,3826,3827],{"v-slot:right":148},[24,3828,3829,3835,3841,3844,3849],{},[27,3830,3831,3832],{},"Title it clearly, such as ",[31,3833,3834],{},"\u003Ccourse> Laptop",[27,3836,3837,3838],{},"Keep key type as ",[31,3839,3840],{},"Authentication Key",[27,3842,3843],{},"Paste the full public key line",[27,3845,951,3846],{},[31,3847,3848],{},"Add SSH key",[27,3850,3851],{},"Never paste the private key",[11,3853,3855,3859],{"id":3854,"level":14},"step-8-test-auth",[16,3856,3858],{"id":3857},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[141,3860,3861,3876],{"gap":143,"left-width":144,"right-width":3003},[146,3862,3863,3865,3869],{"v-slot:left":148},[20,3864,151],{},[115,3866],{"label":3867,"language":118,"src":3868},"test-github-ssh.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-8-test-github-ssh-access-13.sh",[20,3870,3871,3872,3875],{},"If prompted the first time, type ",[31,3873,3874],{},"yes"," to trust GitHub's host key",[146,3877,3878,3880,3883],{"v-slot:right":148},[20,3879,2973],{},[115,3881],{"label":163,"language":2976,"src":3882},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[20,3884,3885],{},"This confirms authentication, then GitHub closes the connection",[11,3887,3889,3893],{"id":3888,"level":14},"step-9-clone-repo",[16,3890,3892],{"id":3891},"step-10-clone-course-repository","Step 10: Clone Course Repository",[141,3894,3895,3936],{"gap":143,"left-width":2460,"right-width":3003},[146,3896,3897,3901,3930],{"v-slot:left":148},[658,3898,3900],{"id":3899},"get-the-ssh-clone-url","Get The SSH Clone URL",[24,3902,3903,3909,3916,3923],{},[27,3904,3905,3906],{},"In your GitHub repository, click ",[31,3907,3908],{},"Code",[27,3910,3911,3912,3915],{},"Choose the ",[31,3913,3914],{},"SSH"," tab",[27,3917,3918,3919,3922],{},"Copy the ",[31,3920,3921],{},"git@github.com:..."," link",[27,3924,3925,3926,3929],{},"Use that link in the ",[31,3927,3928],{},"git clone"," command",[20,3931,3932],{},[926,3933],{"alt":3934,"src":3935,"variant":930},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[146,3937,3938,3941,3945],{"v-slot:right":148},[20,3939,3940],{},"Run from the folder that should contain your course repo:",[115,3942],{"label":3943,"language":118,"src":3944},"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",[2675,3946,3948],{"type":3947},"tip",[20,3949,3950,3951,3954],{},"Before cloning, run ",[31,3952,3953],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[20,3956,160],{},[115,3958],{"label":163,"language":2976,"src":3959},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[20,3961,3962,3963,3966,3967,3970],{},"If you see an empty repository warning, you probably forgot to add ",[31,3964,3965],{},"README.md"," when creating the repo. Create it with ",[31,3968,3969],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,3972,3974,3978,3997,4016,4036],{"id":3973,"level":14},"step-10-set-repo-identity",[16,3975,3977],{"id":3976},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[141,3979,3980,3989],{"gap":143,"left-width":144,"right-width":144},[146,3981,3982,3985],{"v-slot:left":148},[20,3983,3984],{},"Run inside the cloned repository:",[115,3986],{"label":3987,"language":118,"src":3988},"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",[146,3990,3991,3993],{"v-slot:right":148},[20,3992,2973],{},[115,3994],{"label":3995,"language":2976,"src":3996},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[141,3998,3999,4008],{"gap":143,"left-width":144,"right-width":144},[146,4000,4001,4004],{"v-slot:left":148},[20,4002,4003],{},"Then verify:",[115,4005],{"label":4006,"language":118,"src":4007},"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",[146,4009,4010,4012],{"v-slot:right":148},[20,4011,2973],{},[115,4013],{"label":4014,"language":2976,"src":4015},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[24,4017,4018,4024,4030],{},[27,4019,4020,4023],{},[31,4021,4022],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[27,4025,4026,4029],{},[31,4027,4028],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[27,4031,4032,4035],{},[31,4033,4034],{},"core.sshCommand"," tells this repository to use your course GitHub key",[20,4037,4038,4039,4042],{},"These commands set identity for this repository. The ",[31,4040,4041],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,4044,4046,4050,4053,4069],{"id":4045,"level":14},"step-11-invite-collaborators",[16,4047,4049],{"id":4048},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[20,4051,4052],{},"In GitHub, open your course repository:",[24,4054,4055,4058,4063,4066],{},[27,4056,4057],{},"Settings -> Collaborators and teams",[27,4059,4060,4061],{},"Invite ",[31,4062,1158],{},[27,4064,4065],{},"Invite your TA if your section has one",[27,4067,4068],{},"Wait until the invitation shows as sent or accepted",[20,4070,4071],{},"This is so it can be accessed for grading and assistance",[11,4073,4075,4078],{"id":4074,"level":14},"troubleshooting-auth",[16,4076,4077],{"id":4074},"Troubleshooting Auth",[24,4079,4080,4086,4093,4100,4103],{},[27,4081,4082,4085],{},[31,4083,4084],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[27,4087,4088,4089,4092],{},"No loaded key in ",[31,4090,4091],{},"ssh-add -l",": start the agent and add the key again",[27,4094,4095,4096,4099],{},"Wrong key in GitHub: delete it and paste the ",[31,4097,4098],{},".pub"," key again",[27,4101,4102],{},"Wrong account: make sure the success message names your GitHub account",[27,4104,4105],{},"See the slide below for a quick reset sequence",[11,4107,4109,4113,4115,4142],{"id":4108,"level":886},"troubleshooting-auth-recovery",[658,4110,4112],{"id":4111},"quick-reset-sequence","Quick Reset Sequence",[20,4114,151],{},[487,4116,4117,4121,4125,4129,4134,4137],{},[27,4118,4119],{},[31,4120,3623],{},[27,4122,4123],{},[31,4124,3634],{},[27,4126,4127],{},[31,4128,4091],{},[27,4130,4131],{},[31,4132,4133],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[27,4135,4136],{},"Re-paste the public key in GitHub if needed",[27,4138,4139],{},[31,4140,4141],{},"ssh -T git@github.com",[20,4143,2920,4144,4146,4147,4149,4150,4153],{},[31,4145,3623],{}," fails in Git Bash, use ",[31,4148,3630],{},", then repeat the ",[31,4151,4152],{},"ssh-add"," steps",[11,4155,4156,4158,4161],{"id":619,"level":14},[16,4157,622],{"id":619},[20,4159,4160],{},"You are done when all are true:",[24,4162,4163,4168,4175,4180,4183,4188,4191],{},[27,4164,4165,4167],{},[31,4166,2388],{}," works",[27,4169,4170,4172,4173],{},[31,4171,4091],{}," shows ",[31,4174,3508],{},[27,4176,4177,4179],{},[31,4178,4141],{}," names your GitHub account",[27,4181,4182],{},"Your private course repository exists on GitHub",[27,4184,4185,4187],{},[31,4186,1158],{}," and your TA, if applicable, are invited as collaborators",[27,4189,4190],{},"Your local terminal is open to the cloned repository",[27,4192,4193,34,4196,4199],{},[31,4194,4195],{},"git config user.name",[31,4197,4198],{},"git config user.email"," return your repo identity",[11,4201,4202,4204],{"id":648,"level":14},[16,4203,652],{"id":651},[141,4205,4206,4234],{"gap":143,"left-width":144,"right-width":144},[146,4207,4208,4210,4216,4222,4228],{"v-slot:left":148},[658,4209,661],{"id":660},[20,4211,4212,4215],{},[908,4213,4214],{},"Git identity"," - commit name and email saved in repo config",[20,4217,4218,4221],{},[908,4219,4220],{},"SSH key pair"," - private key on your computer, public key in GitHub",[20,4223,4224,4227],{},[908,4225,4226],{},"SSH agent"," - background helper that makes your private key available",[20,4229,4230,4233],{},[908,4231,4232],{},"Clone"," - local copy of a GitHub repository",[146,4235,4236,4238],{"v-slot:right":148},[658,4237,687],{"id":648},[24,4239,4240,4247,4254,4261],{},[27,4241,4242],{},[694,4243,4246],{"href":4244,"rel":4245},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[698],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[27,4248,4249],{},[694,4250,4253],{"href":4251,"rel":4252},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[698],"GitHub Docs: Testing your SSH connection",[27,4255,4256],{},[694,4257,4260],{"href":4258,"rel":4259},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[698],"GitHub Docs: Create a repository",[27,4262,4263],{},[694,4264,4267],{"href":4265,"rel":4266},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[698],"GitHub Docs: Cloning a repository",[11,4269,4270,4272,4274],{"id":717,"level":14},[16,4271,720],{"id":717},[20,4273,723],{},[24,4275,4276,4279,4282,4285,4288,4291,4297],{},[27,4277,4278],{},"Use the correct terminal for your operating system",[27,4280,4281],{},"Authenticate to GitHub with SSH",[27,4283,4284],{},"Find your private course repository on GitHub",[27,4286,4287],{},"Invite course collaborators",[27,4289,4290],{},"Open the local clone in the terminal",[27,4292,4293,4294],{},"Show repo-local Git identity with ",[31,4295,4296],{},"git config",[27,4298,4299],{},"Next: practice the Git commands used for course work",{"title":148,"searchDepth":754,"depth":754,"links":4301},[4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4318,4319,4320,4321,4322,4325,4326,4327],{"id":3259,"depth":754,"text":3262},{"id":3285,"depth":754,"text":3288},{"id":3303,"depth":754,"text":3306},{"id":3328,"depth":754,"text":3331},{"id":3341,"depth":754,"text":3344},{"id":3370,"depth":754,"text":3371},{"id":3407,"depth":754,"text":3408},{"id":3484,"depth":754,"text":3485},{"id":3531,"depth":754,"text":3532},{"id":3598,"depth":754,"text":3599},{"id":3674,"depth":754,"text":3675},{"id":3716,"depth":754,"text":3717,"children":4314},[4315,4316,4317],{"id":3742,"depth":1279,"text":3743},{"id":3774,"depth":1279,"text":3775},{"id":3812,"depth":1279,"text":3813},{"id":3857,"depth":754,"text":3858},{"id":3891,"depth":754,"text":3892},{"id":3976,"depth":754,"text":3977},{"id":4048,"depth":754,"text":4049},{"id":4074,"depth":754,"text":4077,"children":4323},[4324],{"id":4111,"depth":1279,"text":4112},{"id":619,"depth":754,"text":622},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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.","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":3254,"description":4328},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[793,4336,4337,4338],"github","ssh","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":4345,"title":4346,"audience":6,"body":4347,"contentType":775,"course":776,"description":5258,"estimateBasis":5259,"estimatedDiscussionMinutes":1286,"estimatedLiveMinutes":786,"estimatedTotalMinutes":5260,"extension":782,"meta":5261,"module":784,"navigation":785,"order":780,"path":5262,"promptAssist":788,"seo":5263,"status":790,"stem":5264,"tags":5265,"videoDuration":5267,"videoId":5268,"videoLink":5269,"videoTitle":5270,"week":784,"__hash__":5271},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":4348,"toc":5223},[4349,4375,4396,4412,4444,4478,4529,4545,4566,4596,4628,4670,4701,4736,4759,4804,4831,4861,4879,4891,4927,4960,4996,5030,5056,5083,5113,5178,5220],[11,4350,4351,4353,4355],{"id":13,"level":14},[16,4352,18],{"id":13},[20,4354,22],{},[24,4356,4357,4360,4363,4366,4369,4372],{},[27,4358,4359],{},"Explain what the common Git commands do",[27,4361,4362],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[27,4364,4365],{},"Create a branch for practice work",[27,4367,4368],{},"Stage, commit, and push a small change",[27,4370,4371],{},"Open a pull request on GitHub",[27,4373,4374],{},"Investigate a failed push and a merge conflict",[11,4376,4378,4382,4385,4388],{"id":4377,"level":14},"git-vs-github",[16,4379,4381],{"id":4380},"git-versus-github","Git Versus GitHub",[20,4383,4384],{},"Git is the tool that tracks file history",[20,4386,4387],{},"GitHub is a website that hosts a remote copy of a Git repository",[24,4389,4390,4393],{},[27,4391,4392],{},"Git: local terminal workflow",[27,4394,4395],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,4397,4399,4403,4406,4409],{"id":4398,"level":14},"git-stages",[16,4400,4402],{"id":4401},"the-git-stages","The Git Stages",[115,4404],{"language":164,"src":4405},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[20,4407,4408],{},"Common commands:",[115,4410],{"language":164,"src":4411},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,4413,4415,4419,4421,4424,4427,4430],{"id":4414,"level":14},"status-first",[16,4416,4418],{"id":4417},"command-1-git-status","Command 1: git status",[20,4420,151],{},[115,4422],{"language":118,"src":4423},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[20,4425,4426],{},"Use this before and after every important Git action",[20,4428,4429],{},"It tells you:",[24,4431,4432,4435,4438,4441],{},[27,4433,4434],{},"Current branch",[27,4436,4437],{},"Changed files",[27,4439,4440],{},"Staged files",[27,4442,4443],{},"Whether your working tree is clean",[11,4445,4447,4451,4453,4456],{"id":4446,"level":14},"branch-command",[16,4448,4450],{"id":4449},"command-2-git-branch","Command 2: git branch",[20,4452,151],{},[115,4454],{"language":118,"src":4455},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[24,4457,4458,4461,4464],{},[27,4459,4460],{},"Active branch has an asterisk",[27,4462,4463],{},"Branches are separate timelines for work",[27,4465,4466,4467],{},"Branch names are case-sensitive\n",[24,4468,4469],{},[27,4470,4471,34,4474,4477],{},[31,4472,4473],{},"Practice",[31,4475,4476],{},"practice"," are different names",[11,4479,4481,4485,4490,4493],{"id":4480,"level":14},"create-branch",[16,4482,4484],{"id":4483},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[20,4486,4487,4488,2018],{},"Start from ",[31,4489,67],{},[115,4491],{"language":118,"src":4492},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[24,4494,4495,4506],{},[27,4496,4497,4498,4500,4501],{},"First two commands: make sure ",[31,4499,67],{}," is current\n",[24,4502,4503],{},[27,4504,4505],{},"Explained more later",[27,4507,4508,4509],{},"Branch control commands\n",[24,4510,4511,4517,4523],{},[27,4512,4513,4516],{},[31,4514,4515],{},"git checkout -b practice",": create and switch",[27,4518,4519,4522],{},[31,4520,4521],{},"git branch practice",": create only",[27,4524,4525,4528],{},[31,4526,4527],{},"git checkout practice",": switch to existing",[11,4530,4532,4536,4539,4542],{"id":4531,"level":14},"make-file",[16,4533,4535],{"id":4534},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[20,4537,4538],{},"Create a small practice file:",[115,4540],{"language":118,"src":4541},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[20,4543,4544],{},"Expected result: Git shows the new file as untracked",[11,4546,4548,4552,4555,4558,4561],{"id":4547,"level":14},"add-command",[16,4549,4551],{"id":4550},"command-3-git-add","Command 3: git add",[20,4553,4554],{},"Stage the new file:",[115,4556],{"language":118,"src":4557},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[20,4559,4560],{},"Staging means: include this change in the next commit",[24,4562,4563],{},[27,4564,4565],{},"See below for add patterns and verification checks",[11,4567,4569,4573,4576,4579],{"id":4568,"level":886},"add-variants",[658,4570,4572],{"id":4571},"common-git-add-patterns","Common git add Patterns",[20,4574,4575],{},"Use the smallest clear target when possible",[115,4577],{"language":118,"src":4578},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[24,4580,4581,4584,4587],{},[27,4582,4583],{},"Single file: safest when you changed one file",[27,4585,4586],{},"Folder: useful when one feature is grouped in one folder",[27,4588,4589,4592,4593,4595],{},[31,4590,4591],{},"git add .",": convenient, but review ",[31,4594,524],{}," first",[11,4597,4599,4603,4606,4609],{"id":4598,"level":14},"diff-command",[16,4600,4602],{"id":4601},"command-4-git-diff","Command 4: git diff",[20,4604,4605],{},"Before committing, inspect what changed:",[115,4607],{"language":118,"src":4608},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[24,4610,4611,4618,4621,4626],{},[27,4612,4613,4614,4617],{},"New untracked file: ",[31,4615,4616],{},"git diff"," may show nothing",[27,4619,4620],{},"That does not mean the file is missing",[27,4622,1910,4623,4625],{},[31,4624,524],{}," to confirm untracked files",[27,4627,2080],{},[11,4629,4631,4635,4638,4641,4644,4647],{"id":4630,"level":886},"cached-rm",[658,4632,4634],{"id":4633},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[20,4636,4637],{},"If a file was staged by mistake, remove it from staging:",[115,4639],{"language":118,"src":4640},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[20,4642,4643],{},"For a folder:",[115,4645],{"language":118,"src":4646},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[24,4648,4649,4660],{},[27,4650,4651,4654,4655],{},[31,4652,4653],{},"--cached",": remove from staging only\n",[24,4656,4657],{},[27,4658,4659],{},"Keeps the file in your working folder",[27,4661,4662,4664,4665],{},[31,4663,1391],{},": folder mode\n",[24,4666,4667],{},[27,4668,4669],{},"Recursive: include files inside the folder",[11,4671,4673,4677,4680,4683,4686],{"id":4672,"level":14},"commit-command",[16,4674,4676],{"id":4675},"command-5-git-commit","Command 5: git commit",[20,4678,4679],{},"Commit the staged file:",[115,4681],{"language":118,"src":4682},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[20,4684,4685],{},"A commit is a saved checkpoint in your local repository",[24,4687,4688,4699],{},[27,4689,4690,4693,4694],{},[31,4691,4692],{},"-m",": commit message",[24,4695,4696],{},[27,4697,4698],{},"Required, even if the message is an empty string",[27,4700,2080],{},[11,4702,4704,4708,4710,4713,4733],{"id":4703,"level":886},"log-command",[658,4705,4707],{"id":4706},"check-the-local-history","Check The Local History",[20,4709,151],{},[115,4711],{"language":118,"src":4712},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[24,4714,4715,4721,4727],{},[27,4716,4717,4720],{},[31,4718,4719],{},"log",": show commit history",[27,4722,4723,4726],{},[31,4724,4725],{},"--oneline",": one commit per line",[27,4728,4729,4732],{},[31,4730,4731],{},"-5",": show the latest five commits",[20,4734,4735],{},"You should see your latest commit near the top",[11,4737,4739,4743,4746,4749],{"id":4738,"level":14},"push-command",[16,4740,4742],{"id":4741},"command-6-git-push","Command 6: git push",[20,4744,4745],{},"Send the branch to GitHub:",[115,4747],{"language":118,"src":4748},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[24,4750,4751,4756],{},[27,4752,4753,4755],{},[31,4754,191],{},": common remote name for GitHub",[27,4757,4758],{},"Final part: branch you are pushing",[11,4760,4762,4766],{"id":4761,"level":14},"open-pr",[16,4763,4765],{"id":4764},"pull-request","Pull Request",[141,4767,4768,4796],{"gap":143,"left-width":144,"right-width":144},[146,4769,4770,4773,4776,4779,4782,4785],{"v-slot:left":148},[20,4771,4772],{},"On GitHub, open a pull request",[20,4774,4775],{},"Use this direction:",[115,4777],{"language":164,"src":4778},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[20,4780,4781],{},"Use a clear description:",[115,4783],{"language":164,"src":4784},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[24,4786,4787,4790,4793],{},[27,4788,4789],{},"Review page before merge",[27,4791,4792],{},"Shows what will change",[27,4794,4795],{},"Captures branch evidence",[146,4797,4798],{"v-slot:right":148},[20,4799,4800],{},[926,4801],{"alt":4802,"src":4803,"variant":930},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,4805,4807,4811,4814,4822,4825,4828],{"id":4806,"level":14},"merge-pr",[16,4808,4810],{"id":4809},"merge-and-sync","Merge And Sync",[20,4812,4813],{},"After GitHub merge:",[24,4815,4816],{},[27,4817,4818,4819,4821],{},"Local ",[31,4820,67],{}," is not updated automatically",[20,4823,4824],{},"Sync it:",[115,4826],{"language":118,"src":4827},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[20,4829,4830],{},"Remote changes must be pulled down intentionally",[11,4832,4834,4838,4841,4858],{"id":4833,"level":14},"why-prs",[16,4835,4837],{"id":4836},"why-pull-requests-matter","Why Pull Requests Matter",[20,4839,4840],{},"Pull requests create evidence:",[24,4842,4843,4846,4849,4852,4855],{},[27,4844,4845],{},"Which branch changed",[27,4847,4848],{},"Which files changed",[27,4850,4851],{},"What discussion or explanation was provided",[27,4853,4854],{},"Chance to review risky changes before merging",[27,4856,4857],{},"When the change was merged",[20,4859,4860],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,4862,4864,4868,4871],{"id":4863,"level":14},"exploration-intro",[16,4865,4867],{"id":4866},"troubleshooting-explorations","Troubleshooting Explorations",[20,4869,4870],{},"The next slides use controlled problems to practice recovery",[24,4872,4873,4876],{},[27,4874,4875],{},"The goal is not avoiding every error",[27,4877,4878],{},"The goal is reading output, identifying state, and recovering without guessing",[11,4880,4882,4885,4888],{"id":4881,"level":14},"exploration-setup",[16,4883,4884],{"id":4881},"Exploration Setup",[20,4886,4887],{},"Create a conflict practice branch:",[115,4889],{"language":118,"src":4890},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,4892,4894,4898,4904,4911,4916,4919,4922],{"id":4893,"level":14},"exploration-issue-1",[16,4895,4897],{"id":4896},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[20,4899,4900,4901],{},"On GitHub, switch to ",[31,4902,4903],{},"practice-conflict",[20,4905,4906,4907,4910],{},"Edit one line in ",[31,4908,4909],{},"myFile.txt"," directly on GitHub and commit the change",[24,4912,4913],{},[27,4914,4915],{},"Use the same line you will change locally",[20,4917,4918],{},"Back locally, edit that same line and commit:",[115,4920],{"language":118,"src":4921},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[24,4923,4924],{},[27,4925,4926],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,4928,4930,4934,4937],{"id":4929,"level":886},"issue-1-push-without-pulling",[658,4931,4933],{"id":4932},"try-push-without-pulling","Try Push Without Pulling",[20,4935,4936],{},"Push the local commit before pulling the GitHub commit:",[141,4938,4939,4952],{"gap":143,"left-width":144,"right-width":144},[146,4940,4941,4944],{"v-slot:left":148},[115,4942],{"language":118,"src":4943},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[24,4945,4946,4949],{},[27,4947,4948],{},"Expected result: push rejected",[27,4950,4951],{},"Reason: GitHub has a commit your local branch does not have",[146,4953,4954],{"v-slot:right":148},[20,4955,4956],{},[926,4957],{"alt":4958,"src":4959,"variant":930},"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,4961,4963,4967],{"id":4962,"level":886},"issue-1-read-output",[658,4964,4966],{"id":4965},"pull-the-remote-change","Pull The Remote Change",[141,4968,4969,4988],{"gap":143,"left-width":144,"right-width":144},[146,4970,4971,4974,4977,4980,4985],{"v-slot:left":148},[20,4972,4973],{},"The usual next command is:",[115,4975],{"language":118,"src":4976},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[20,4978,4979],{},"If Git asks how to reconcile divergent branches:",[24,4981,4982],{},[27,4983,4984],{},"Use merge behavior for this course practice",[115,4986],{"language":118,"src":4987},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[146,4989,4990],{"v-slot:right":148},[20,4991,4992],{},[926,4993],{"alt":4994,"src":4995,"variant":930},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,4997,4999,5003,5006,5010,5013,5016,5019],{"id":4998,"level":14},"exploration-issue-2",[16,5000,5002],{"id":5001},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[20,5004,5005],{},"After pulling, Git should report a conflict",[20,5007,3799,5008],{},[31,5009,4909],{},[20,5011,5012],{},"You may see markers like:",[115,5014],{"language":164,"src":5015},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[20,5017,5018],{},"Conflict markers show:",[24,5020,5021,5024,5027],{},[27,5022,5023],{},"Your local version",[27,5025,5026],{},"The GitHub version",[27,5028,5029],{},"The part Git could not combine automatically",[11,5031,5033,5037,5043,5046,5049,5052],{"id":5032,"level":886},"resolve-conflict",[658,5034,5036],{"id":5035},"resolve-the-conflict","Resolve The Conflict",[20,5038,5039,5040,5042],{},"Edit ",[31,5041,4909],{}," so it contains the final text you want",[20,5044,5045],{},"Remove all conflict markers",[20,5047,5048],{},"Then run:",[115,5050],{"language":118,"src":5051},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[24,5053,5054],{},[27,5055,2080],{},[11,5057,5059,5063,5066],{"id":5058,"level":886},"verify-conflict-resolution",[658,5060,5062],{"id":5061},"verify-the-recovery","Verify The Recovery",[20,5064,5065],{},"Check:",[24,5067,5068,5072,5075,5080],{},[27,5069,5070,616],{},[31,5071,524],{},[27,5073,5074],{},"GitHub shows the updated branch",[27,5076,5077,5079],{},[31,5078,4909],{}," contains the final text",[27,5081,5082],{},"No conflict markers remain",[11,5084,5085,5087],{"id":576,"level":14},[16,5086,579],{"id":576},[24,5088,5089,5092,5095,5098,5101,5110],{},[27,5090,5091],{},"Committing on the wrong branch",[27,5093,5094],{},"Forgetting to push after committing",[27,5096,5097],{},"Forgetting to pull after merging on GitHub",[27,5099,5100],{},"Leaving conflict markers in a file",[27,5102,5103,5104,1961,5107],{},"Using vague branch names like ",[31,5105,5106],{},"stuff",[31,5108,5109],{},"final",[27,5111,5112],{},"Making several unrelated changes in one commit",[11,5114,5115,5117],{"id":648,"level":14},[16,5116,652],{"id":651},[141,5118,5119,5143],{"gap":143,"left-width":144,"right-width":144},[146,5120,5121,5123],{"v-slot:left":148},[658,5122,661],{"id":660},[24,5124,5125,5128,5131,5134,5137,5140],{},[27,5126,5127],{},"Working folder: files you can edit",[27,5129,5130],{},"Staging area: changes selected for the next commit",[27,5132,5133],{},"Commit: local saved checkpoint",[27,5135,5136],{},"Remote: GitHub copy of the repository",[27,5138,5139],{},"Pull request: GitHub page for reviewing and merging branch work",[27,5141,5142],{},"Conflict: a change Git cannot merge automatically",[146,5144,5145,5147],{"v-slot:right":148},[658,5146,687],{"id":648},[24,5148,5149,5156,5163,5170],{},[27,5150,709,5151],{},[694,5152,5155],{"href":5153,"rel":5154},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[698],"Git Basics",[27,5157,709,5158],{},[694,5159,5162],{"href":5160,"rel":5161},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[698],"Basic Branching and Merging",[27,5164,692,5165],{},[694,5166,5169],{"href":5167,"rel":5168},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[698],"Creating a pull request",[27,5171,5172,5173],{},"Oh Shit, Git!?!: ",[694,5174,5177],{"href":5175,"rel":5176},"https:\u002F\u002Fohshitgit.com\u002F",[698],"Common Git recovery situations",[11,5179,5180,5182],{"id":717,"level":14},[16,5181,720],{"id":717},[141,5183,5186,5210],{"gap":782,"left-width":5184,"right-width":5185},"0.72fr","1.38fr",[146,5187,5188,5190],{"v-slot:left":148},[20,5189,723],{},[24,5191,5192,5198,5201,5204,5207],{},[27,5193,5194,5195,5197],{},"Read ",[31,5196,524],{}," before choosing the next command",[27,5199,5200],{},"Move a change from working folder to staging area to commit",[27,5202,5203],{},"Push a branch to GitHub and open a pull request",[27,5205,5206],{},"Recognize when a failed push or conflict needs recovery",[27,5208,5209],{},"Next: open the cloned repository in VS Code",[146,5211,5212,5215],{"v-slot:right":148},[20,5213,5214],{},"Git\u002FGitHub flow:",[5216,5217],"figure-image",{"alt":5218,"src":5219},"Lane diagram showing local Git commands moving from the base branch to a feature or homework branch, then pushing to GitHub for pull request review and merge, then pulling the base branch back locally","\u002Fimages\u002Fshared\u002Fgit-github-lane-flow.svg",[20,5221,5222],{},"::",{"title":148,"searchDepth":754,"depth":754,"links":5224},[5225,5226,5227,5228,5229,5230,5231,5232,5235,5238,5241,5242,5243,5244,5245,5246,5247,5251,5255,5256,5257],{"id":13,"depth":754,"text":18},{"id":4380,"depth":754,"text":4381},{"id":4401,"depth":754,"text":4402},{"id":4417,"depth":754,"text":4418},{"id":4449,"depth":754,"text":4450},{"id":4483,"depth":754,"text":4484},{"id":4534,"depth":754,"text":4535},{"id":4550,"depth":754,"text":4551,"children":5233},[5234],{"id":4571,"depth":1279,"text":4572},{"id":4601,"depth":754,"text":4602,"children":5236},[5237],{"id":4633,"depth":1279,"text":4634},{"id":4675,"depth":754,"text":4676,"children":5239},[5240],{"id":4706,"depth":1279,"text":4707},{"id":4741,"depth":754,"text":4742},{"id":4764,"depth":754,"text":4765},{"id":4809,"depth":754,"text":4810},{"id":4836,"depth":754,"text":4837},{"id":4866,"depth":754,"text":4867},{"id":4881,"depth":754,"text":4884},{"id":4896,"depth":754,"text":4897,"children":5248},[5249,5250],{"id":4932,"depth":1279,"text":4933},{"id":4965,"depth":1279,"text":4966},{"id":5001,"depth":754,"text":5002,"children":5252},[5253,5254],{"id":5035,"depth":1279,"text":5036},{"id":5061,"depth":1279,"text":5062},{"id":576,"depth":754,"text":579},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",{"title":4346,"description":5258},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[793,794,5266],"pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":5273,"title":5274,"audience":6,"body":5275,"contentType":775,"course":776,"description":6045,"estimateBasis":6046,"estimatedDiscussionMinutes":1285,"estimatedLiveMinutes":1287,"estimatedTotalMinutes":780,"extension":782,"meta":6047,"module":784,"navigation":785,"order":6048,"path":6049,"promptAssist":788,"seo":6050,"status":790,"stem":6051,"tags":6052,"videoDuration":6056,"videoId":6057,"videoLink":6058,"videoTitle":6059,"week":784,"__hash__":6060},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":5276,"toc":6023},[5277,5294,5312,5333,5358,5392,5423,5501,5578,5680,5708,5773,5850,5874,5901,5919,5943,5994],[11,5278,5280,5283],{"id":5279,"level":14},"local-development-environment-title",[16,5281,5274],{"id":5282},"local-development-environment-setup",[24,5284,5285,5288,5291],{},[27,5286,5287],{},"VS Code for editing course files",[27,5289,5290],{},"Course profile for Internet Applications extensions",[27,5292,5293],{},"Optional local PHP check on your own computer",[11,5295,5296,5298],{"id":1368,"level":14},[16,5297,1371],{"id":1368},[24,5299,5300,5303,5306,5309],{},[27,5301,5302],{},"Install VS Code",[27,5304,5305],{},"Open the course repository root",[27,5307,5308],{},"Install the required extensions for the course",[27,5310,5311],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,5313,5315,5318],{"id":5314,"level":14},"what-this-setup-does",[16,5316,5317],{"id":5314},"What This Setup Does",[24,5319,5320,5323,5326],{},[27,5321,5322],{},"VS Code: editor for course files",[27,5324,5325],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[27,5327,5328,5329,5332],{},"Optional host PHP: quick ",[31,5330,5331],{},"php -v"," check and editor support",[11,5334,5336,5339],{"id":5335,"level":14},"step-1-install-vs-code",[16,5337,5338],{"id":5335},"Step 1: Install VS Code",[24,5340,5341,5349,5352,5355],{},[27,5342,5343,5344],{},"Download: ",[694,5345,5348],{"href":5346,"rel":5347},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[698],"Visual Studio Code",[27,5350,5351],{},"Install like a normal desktop app",[27,5353,5354],{},"Do not install VS Code inside your repository folder",[27,5356,5357],{},"VS Code is the editor; the repo is the workspace folder",[11,5359,5361,5364,5367,5389],{"id":5360,"level":14},"step-2-open-the-repository",[16,5362,5363],{"id":5360},"Step 2: Open The Repository",[20,5365,5366],{},"After the course repo is cloned:",[24,5368,5369,5378,5381,5386],{},[27,5370,5371,5372,102,5375],{},"VS Code -> ",[31,5373,5374],{},"File",[31,5376,5377],{},"Open Folder",[27,5379,5380],{},"Choose the repository root",[27,5382,5383,5384],{},"Folder name should match ",[31,5385,3435],{},[27,5387,5388],{},"Trust the workspace only if it is your cloned GitHub repo",[20,5390,5391],{},"Do not open a ZIP copy or clone the same repo again",[11,5393,5395,5399,5420],{"id":5394,"level":14},"step-3-create-course-profile",[16,5396,5398],{"id":5397},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[24,5400,5401,5407,5414,5417],{},[27,5402,5403,5404],{},"Gear icon -> ",[31,5405,5406],{},"Profiles",[27,5408,294,5409,1961,5411],{},[31,5410,776],{},[31,5412,5413],{},"PHP",[27,5415,5416],{},"Switch into that profile",[27,5418,5419],{},"Install course extensions there",[20,5421,5422],{},"Profiles keep this course setup separate from other projects",[11,5424,5426,5429,5433],{"id":5425,"level":14},"step-4-install-extensions",[16,5427,5428],{"id":5425},"Step 4: Install Extensions",[658,5430,5432],{"id":5431},"start-with-these","Start With These",[24,5434,5435,5443,5451,5459,5467,5475,5490,5498],{},[27,5436,5437,5438],{},"Auto Rename Tag (Jun Han)\n",[24,5439,5440],{},[27,5441,5442],{},"Auto-completes matching HTML tags while you edit",[27,5444,5445,5446],{},"Bracket Lens (wraith13)\n",[24,5447,5448],{},[27,5449,5450],{},"Adds readability cues for closing brackets",[27,5452,5453,5454],{},"GitLens (GitKraken)\n",[24,5455,5456],{},[27,5457,5458],{},"Required: Git history, blame, and branch visibility in-editor",[27,5460,5461,5462],{},"MySQL (cweijan)\n",[24,5463,5464],{},[27,5465,5466],{},"Required later: connect to and inspect course database tables",[27,5468,5469,5470],{},"PHP Intelephense (Ben Mewburn)\n",[24,5471,5472],{},[27,5473,5474],{},"PHP language support, syntax checks, and warnings",[27,5476,5477,5478],{},"Todo Tree (Gruntfuggly)\n",[24,5479,5480],{},[27,5481,5482,5483,731,5486,5489],{},"Finds and lists ",[31,5484,5485],{},"TODO",[31,5487,5488],{},"FIXME",", and similar comments",[27,5491,5492,5493],{},"WakaTime\n",[24,5494,5495],{},[27,5496,5497],{},"Required in sections that use time tracking; needs your API key",[27,5499,5500],{},"See the slides below for MySQL and WakaTime setup",[11,5502,5504,5508],{"id":5503,"level":886},"step-4a-setup-mysql-extension",[16,5505,5507],{"id":5506},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[141,5509,5511,5570],{"gap":143,"left-width":2460,"right-width":3003,"align":5510},"center",[146,5512,5513,5517],{"v-slot:left":148},[658,5514,5516],{"id":5515},"connection-settings","Connection Settings",[24,5518,5519,5522,5567],{},[27,5520,5521],{},"Open the MySQL panel from the VS Code sidebar",[27,5523,5524,5525],{},"Create a new connection with your course database details",[24,5526,5527,5533,5539,5542,5545],{},[27,5528,5529,5530],{},"Host: ",[31,5531,5532],{},"db.ethereallab.app",[27,5534,5535,5536],{},"Port: ",[31,5537,5538],{},"3306",[27,5540,5541],{},"Username: your UCID",[27,5543,5544],{},"Database: your UCID",[27,5546,5547,5548],{},"Password: from your generated connection string\n",[24,5549,5550,5558],{},[27,5551,5552,5553],{},"Get it from the ",[694,5554,5557],{"href":5555,"rel":5556},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[698],"course database page",[27,5559,5560,5561,34,5564],{},"Use the 12 characters between ",[31,5562,5563],{},"ucid:",[31,5565,5566],{},"@",[27,5568,5569],{},"Save this connection; you will reuse it in later database lessons",[146,5571,5572],{"v-slot:right":148},[20,5573,5574],{},[926,5575],{"alt":5576,"src":5577,"variant":930},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,5579,5581,5585],{"id":5580,"level":886},"step-4b-setup-wakatime",[16,5582,5584],{"id":5583},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[141,5586,5588,5643],{"gap":143,"left-width":3411,"right-width":5587,"align":5510},"1.05fr",[146,5589,5590,5594],{"v-slot:left":148},[658,5591,5593],{"id":5592},"setup-order","Setup Order",[24,5595,5596,5603,5606,5609,5612,5615,5632,5637,5640],{},[27,5597,2434,5598],{},[694,5599,5602],{"href":5600,"rel":5601},"https:\u002F\u002Fwakatime.com\u002Fsignup",[698],"WakaTime",[27,5604,5605],{},"Create or open your account",[27,5607,5608],{},"Copy your API key from account settings",[27,5610,5611],{},"In VS Code, search Extensions for WakaTime",[27,5613,5614],{},"Install the WakaTime extension",[27,5616,5617,5618],{},"Open Command Palette:",[24,5619,5620,5626],{},[27,5621,5622,5623],{},"Windows\u002FLinux: ",[31,5624,5625],{},"Ctrl+Shift+P",[27,5627,5628,5629],{},"macOS: ",[31,5630,5631],{},"Cmd+Shift+P",[27,5633,3109,5634],{},[31,5635,5636],{},"WakaTime: API Key",[27,5638,5639],{},"Paste your API key",[27,5641,5642],{},"Restart VS Code if tracking does not appear right away",[146,5644,5645,5650,5657,5662,5669,5674],{"v-slot:right":148},[487,5646,5647],{},[27,5648,5649],{},"WakaTime account settings:",[20,5651,5652],{},[926,5653],{"alt":5654,"src":5655,"variant":930,"max-height":5656},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[487,5658,5659],{"start":754},[27,5660,5661],{},"VS Code extension search:",[20,5663,5664],{},[926,5665],{"alt":5666,"src":5667,"variant":930,"max-height":5668},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[487,5670,5671],{"start":1279},[27,5672,5673],{},"VS Code API key command:",[20,5675,5676],{},[926,5677],{"alt":5678,"src":5679,"variant":930,"max-height":5668},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,5681,5683,5686],{"id":5682,"level":14},"step-5-optional-local-php",[16,5684,5685],{"id":5682},"Step 5: Optional Local PHP",[24,5687,5688,5691,5694,5702,5705],{},[27,5689,5690],{},"Useful for editor support",[27,5692,5693],{},"Useful for quick terminal checks",[27,5695,5696,5697],{},"Not the main course runtime\n",[24,5698,5699],{},[27,5700,5701],{},"Viable backup solution if VM lesson has issues",[27,5703,5704],{},"VM and Render still run the real app path",[27,5706,5707],{},"See the slides below for OS-specific install notes",[11,5709,5711,5714],{"id":5710,"level":886},"step-5a-windows-php-zip",[16,5712,5713],{"id":5710},"Step 5A: Windows PHP ZIP",[141,5715,5716,5747],{"gap":143,"left-width":144,"right-width":144},[146,5717,5718,5722],{"v-slot:left":148},[658,5719,5721],{"id":5720},"download-and-extract","Download And Extract",[24,5723,5724,5727,5737,5742],{},[27,5725,5726],{},"Download PHP for Windows as a ZIP",[27,5728,5729,5730],{},"Extract it outside your repository",[24,5731,5732],{},[27,5733,1538,5734],{},[31,5735,5736],{},"C:\\tools\\php",[27,5738,5739,5740],{},"Add that extracted PHP folder to the user ",[31,5741,2228],{},[27,5743,5744,5745],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[31,5746,2228],{},[146,5748,5749,5753,5769],{"v-slot:right":148},[658,5750,5752],{"id":5751},"visual-checks","Visual Checks",[24,5754,5755,5761,5766],{},[27,5756,5757,5758],{},"The extracted folder contains ",[31,5759,5760],{},"php.exe",[27,5762,5763,5764],{},"The Path entry points to the folder, not to ",[31,5765,5760],{},[27,5767,5768],{},"A new terminal can run:",[115,5770],{"language":118,"src":5771,"label":5772},"\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,5774,5776,5779],{"id":5775,"level":886},"step-5b-macos-homebrew-php",[16,5777,5778],{"id":5775},"Step 5B: macOS Homebrew PHP",[141,5780,5781,5812],{"gap":143,"left-width":144,"right-width":144},[146,5782,5783,5787],{"v-slot:left":148},[658,5784,5786],{"id":5785},"install-homebrew","Install Homebrew",[24,5788,5789,5792,5800,5803,5806,5809],{},[27,5790,5791],{},"Open Terminal",[27,5793,5794,5795],{},"Copy the install command from ",[694,5796,5799],{"href":5797,"rel":5798},"https:\u002F\u002Fbrew.sh\u002F",[698],"brew.sh",[27,5801,5802],{},"Expect Terminal to ask for your Mac password",[27,5804,5805],{},"Expect Homebrew to mention Command Line Tools if needed",[27,5807,5808],{},"At the end, Homebrew may print \"Next steps\"",[27,5810,5811],{},"Run those \"Next steps\" commands if shown",[146,5813,5814,5818,5822,5825],{"v-slot:right":148},[658,5815,5817],{"id":5816},"then-install-php","Then Install PHP",[115,5819],{"language":118,"src":5820,"label":5821},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fmacos-install-php-homebrew-04.sh","macos-php.sh",[20,5823,5824],{},"Look for:",[24,5826,5827,5833,5838,5844],{},[27,5828,5829,5832],{},[31,5830,5831],{},"brew --version"," prints a version",[27,5834,5835,5837],{},[31,5836,5331],{}," prints PHP 8 output",[27,5839,5840,5841],{},"Apple Silicon Macs commonly use ",[31,5842,5843],{},"\u002Fopt\u002Fhomebrew",[27,5845,5846,5847],{},"Intel Macs commonly use ",[31,5848,5849],{},"\u002Fusr\u002Flocal",[11,5851,5853,5857,5859,5863],{"id":5852,"level":886},"step-5c-linux-php-cli",[16,5854,5856],{"id":5855},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[20,5858,151],{},[115,5860],{"language":118,"src":5861,"label":5862},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Flinux-install-php-cli-05.sh","linux-php.sh",[24,5864,5865,5868,5871],{},[27,5866,5867],{},"This installs command-line PHP",[27,5869,5870],{},"This is only for local terminal checks",[27,5872,5873],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,5875,5877,5880,5882,5885,5887,5890],{"id":5876,"level":14},"step-6-verify-optional-php",[16,5878,5879],{"id":5876},"Step 6: Verify Optional PHP",[20,5881,151],{},[115,5883],{"language":118,"src":5884},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[20,5886,160],{},[115,5888],{"language":164,"src":5889},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[24,5891,5892,5895,5898],{},[27,5893,5894],{},"Exact version can differ",[27,5896,5897],{},"PHP 8 output means the terminal can find PHP",[27,5899,5900],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,5902,5903,5905],{"id":576,"level":14},[16,5904,579],{"id":576},[24,5906,5907,5910,5913,5916],{},[27,5908,5909],{},"Installing tools inside the repository folder",[27,5911,5912],{},"Opening the parent folder instead of the repo root",[27,5914,5915],{},"Editing a ZIP copy instead of the cloned repo",[27,5917,5918],{},"Installing extensions in the wrong VS Code profile",[11,5920,5921,5923],{"id":619,"level":14},[16,5922,622],{"id":619},[24,5924,5925,5928,5931,5934,5937],{},[27,5926,5927],{},"VS Code opens your course repository root",[27,5929,5930],{},"Course profile is active",[27,5932,5933],{},"PHP Intelephense is installed",[27,5935,5936],{},"GitLens is installed",[27,5938,5939,5940,5942],{},"Optional: ",[31,5941,5331],{}," prints a PHP 8 version",[11,5944,5945,5947],{"id":651,"level":14},[16,5946,652],{"id":651},[141,5948,5949,5967],{"gap":143,"left-width":144,"right-width":144},[146,5950,5951,5953],{"v-slot:left":148},[658,5952,661],{"id":660},[24,5954,5955,5958,5961,5964],{},[27,5956,5957],{},"IDE: editor with development tools",[27,5959,5960],{},"Extension: add-on that changes VS Code behavior",[27,5962,5963],{},"Profile: saved VS Code setup",[27,5965,5966],{},"PATH: system setting used to find commands",[146,5968,5969,5971],{"v-slot:right":148},[658,5970,687],{"id":648},[24,5972,5973,5980,5987],{},[27,5974,5975],{},[694,5976,5979],{"href":5977,"rel":5978},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[698],"VS Code Getting Started",[27,5981,5982],{},[694,5983,5986],{"href":5984,"rel":5985},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[698],"VS Code Profiles",[27,5988,5989],{},[694,5990,5993],{"href":5991,"rel":5992},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[698],"PHP Installation",[11,5995,5996,5998],{"id":717,"level":14},[16,5997,720],{"id":717},[24,5999,6000,6003,6006,6009,6020],{},[27,6001,6002],{},"VS Code installed as the course editor",[27,6004,6005],{},"Repository opens from its root folder",[27,6007,6008],{},"Course extensions live in a course profile",[27,6010,6011,6012],{},"Local PHP is optional for this Internet Applications path\n",[24,6013,6014,6017],{},[27,6015,6016],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[27,6018,6019],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[27,6021,6022],{},"Next: copy the instructor template into the repository",{"title":148,"searchDepth":754,"depth":754,"links":6024},[6025,6026,6027,6028,6029,6030,6031,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044],{"id":5282,"depth":754,"text":5274},{"id":1368,"depth":754,"text":1371},{"id":5314,"depth":754,"text":5317},{"id":5335,"depth":754,"text":5338},{"id":5360,"depth":754,"text":5363},{"id":5397,"depth":754,"text":5398},{"id":5425,"depth":754,"text":5428,"children":6032},[6033],{"id":5431,"depth":1279,"text":5432},{"id":5506,"depth":754,"text":5507},{"id":5583,"depth":754,"text":5584},{"id":5682,"depth":754,"text":5685},{"id":5710,"depth":754,"text":5713},{"id":5775,"depth":754,"text":5778},{"id":5855,"depth":754,"text":5856},{"id":5876,"depth":754,"text":5879},{"id":576,"depth":754,"text":579},{"id":619,"depth":754,"text":622},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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":5274,"description":6045},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[6053,6054,6055],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":6062,"title":6063,"audience":6,"body":6064,"contentType":775,"course":776,"description":7110,"estimateBasis":7111,"estimatedDiscussionMinutes":779,"estimatedLiveMinutes":2353,"estimatedTotalMinutes":7112,"extension":782,"meta":7113,"module":784,"navigation":785,"order":7112,"path":7114,"promptAssist":788,"seo":7115,"status":790,"stem":7116,"tags":7117,"videoDuration":7118,"videoId":7119,"videoLink":7120,"videoTitle":7121,"week":784,"__hash__":7122},"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":6065,"toc":7082},[6066,6095,6137,6165,6198,6229,6275,6368,6412,6457,6502,6545,6617,6674,6747,6801,6877,6945,6977,7029,7053],[11,6067,6068,6070,6073],{"id":13,"level":14},[16,6069,18],{"id":13},[20,6071,6072],{},"By the end, you should have:",[24,6074,6075,6078,6081,6087,6092],{},[27,6076,6077],{},"Cloned course repository open in the terminal",[27,6079,6080],{},"Starter template copied into the repository root",[27,6082,6083,6084],{},"Baseline commit on ",[31,6085,6086],{},"Module01-Course-Template",[27,6088,6089,6090],{},"Pull request merged into ",[31,6091,67],{},[27,6093,6094],{},"Clean working tree before moving on",[11,6096,6098,6102],{"id":6097,"level":14},"step-1-open-clone",[16,6099,6101],{"id":6100},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[141,6103,6104,6112],{"gap":143,"left-width":144,"right-width":144},[146,6105,6106,6108],{"v-slot:left":148},[20,6107,151],{},[115,6109],{"language":118,"src":6110,"label":6111},"\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",[146,6113,6114,6116,6119],{"v-slot:right":148},[20,6115,160],{},[115,6117],{"language":2976,"src":6118,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[24,6120,6121,6126,6131],{},[27,6122,6123,6125],{},[31,6124,1455],{},": current working directory",[27,6127,6128,6130],{},[31,6129,524],{},": current branch and file state",[27,6132,6133,6134,6136],{},"Important check: ",[31,6135,1455],{}," ends with your repository folder",[11,6138,6140,6144,6147,6150],{"id":6139,"level":14},"step-2-open-vscode",[16,6141,6143],{"id":6142},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[20,6145,6146],{},"Run from inside the cloned repository folder:",[115,6148],{"language":118,"src":6149},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-2-open-the-reposito-01.sh",[24,6151,6152,6157,6162],{},[27,6153,6154,6156],{},[31,6155,31],{},": opens VS Code from the terminal",[27,6158,6159,6161],{},[31,6160,1520],{}," means \"this current folder\"",[27,6163,6164],{},"VS Code should show your repository folder, not the parent folder",[11,6166,6168,6172],{"id":6167,"level":14},"step-3-download-template",[16,6169,6171],{"id":6170},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[24,6173,6174,6186,6189,6192,6195],{},[27,6175,6176,6177],{},"Open the instructor template repository",[24,6178,6179],{},[27,6180,6181],{},[694,6182,6185],{"href":6183,"rel":6184},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[698],"IT202-2026",[27,6187,6188],{},"Download the ZIP",[27,6190,6191],{},"Extract the ZIP",[27,6193,6194],{},"Copy scaffold contents into your repository root",[27,6196,6197],{},"See the slide below for the copy rule",[11,6199,6201,6205,6208,6211,6226],{"id":6200,"level":886},"template-copy-rule",[658,6202,6204],{"id":6203},"copy-rule","Copy Rule",[20,6206,6207],{},"Copy the contents of the extracted template folder",[20,6209,6210],{},"Do not copy:",[24,6212,6213,6216,6223],{},[27,6214,6215],{},"The extracted wrapper folder as one extra nested folder",[27,6217,6218,6219,6222],{},"The template repository's hidden ",[31,6220,6221],{},".git"," folder",[27,6224,6225],{},"Old files from a different semester",[20,6227,6228],{},"Repository root should contain the starter folders directly",[11,6230,6232,6236,6239,6242],{"id":6231,"level":14},"step-4-check-structure",[16,6233,6235],{"id":6234},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[20,6237,6238],{},"After copying, repository root should look similar to:",[115,6240],{"language":164,"src":6241},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-4-check-the-starter-02.txt",[24,6243,6244,6249,6258,6272],{},[27,6245,6246,6248],{},[31,6247,1587],{}," should be directly inside your repository root",[27,6250,6251,6252,6255,6256],{},"Module folders and ",[31,6253,6254],{},"project"," live inside ",[31,6257,1587],{},[27,6259,6260,731,6263,734,6266,6269,6270],{},[31,6261,6262],{},"lib",[31,6264,6265],{},"partials",[31,6267,6268],{},"sql"," stay outside ",[31,6271,1587],{},[27,6273,6274],{},"See the slide below for the public\u002Fprivate folder boundary",[11,6276,6278,6282,6365],{"id":6277,"level":886},"public-html-boundary",[658,6279,6281],{"id":6280},"public-and-private-boundary","Public And Private Boundary",[24,6283,6284,6318,6340,6345,6350,6356,6362],{},[27,6285,6286,6288,6289],{},[31,6287,1587],{},": web root Apache can serve\n",[24,6290,6291,6301,6306,6312],{},[27,6292,6293,6296,6297,6300],{},[31,6294,6295],{},"m01"," through ",[31,6298,6299],{},"m10",": module practice folders",[27,6302,6303,6305],{},[31,6304,6254],{},": course project folder",[27,6307,6308,6311],{},[31,6309,6310],{},"index.php",": first browser entry point",[27,6313,6314,6317],{},[31,6315,6316],{},"test_db.php",": database connection check",[27,6319,6320,6322,6323],{},[31,6321,6262],{},": reusable PHP helpers\n",[24,6324,6325,6331],{},[27,6326,6327,6330],{},[31,6328,6329],{},".env.sample",": example local config file",[27,6332,6333,34,6336,6339],{},[31,6334,6335],{},"config.php",[31,6337,6338],{},"db.php",": config and database helpers",[27,6341,6342,6344],{},[31,6343,6265],{},": shared page pieces",[27,6346,6347,6349],{},[31,6348,6268],{},": database setup scripts",[27,6351,6352,6355],{},[31,6353,6354],{},"Dockerfile",": consistent runtime setup",[27,6357,6358,6361],{},[31,6359,6360],{},"structure.md",": starter layout notes",[27,6363,6364],{},"Private folders should not be opened directly in the browser",[20,6366,6367],{},"Later server setup expects this folder boundary",[11,6369,6371,6375],{"id":6370,"level":14},"step-5-check-status",[16,6372,6374],{"id":6373},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[141,6376,6377,6385],{"gap":143,"left-width":144,"right-width":144},[146,6378,6379,6381],{"v-slot:left":148},[20,6380,151],{},[115,6382],{"language":118,"src":6383,"label":6384},"\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",[146,6386,6387,6390,6393],{"v-slot:right":148},[20,6388,6389],{},"Expected idea:",[115,6391],{"language":164,"src":6392,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[24,6394,6395,6401,6406,6409],{},[27,6396,6397,6400],{},[31,6398,6399],{},"git checkout -b",": create and move to a new branch",[27,6402,6403,6404],{},"Branch name: ",[31,6405,6086],{},[27,6407,6408],{},"New files listed as untracked",[27,6410,6411],{},"No changes means likely wrong folder or copy missed",[11,6413,6415,6419],{"id":6414,"level":14},"step-6-stage",[16,6416,6418],{"id":6417},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[141,6420,6421,6429],{"gap":143,"left-width":144,"right-width":144},[146,6422,6423,6425],{"v-slot:left":148},[20,6424,151],{},[115,6426],{"language":118,"src":6427,"label":6428},"\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",[146,6430,6431,6434,6452,6454],{"v-slot:right":148},[20,6432,6433],{},"What this means:",[24,6435,6436,6442,6447],{},[27,6437,6438,6441],{},[31,6439,6440],{},"git add",": choose files for the next commit",[27,6443,6444,6446],{},[31,6445,1520],{}," means current folder and contents",[27,6448,6449,6451],{},[31,6450,524],{},": verify what is staged before committing",[20,6453,6389],{},[115,6455],{"language":164,"src":6456,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,6458,6460,6464],{"id":6459,"level":14},"step-7-commit",[16,6461,6463],{"id":6462},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[141,6465,6466,6474],{"gap":143,"left-width":144,"right-width":144},[146,6467,6468,6470],{"v-slot:left":148},[20,6469,151],{},[115,6471],{"language":118,"src":6472,"label":6473},"\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",[146,6475,6476,6478,6481],{"v-slot:right":148},[20,6477,6389],{},[115,6479],{"language":164,"src":6480,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[24,6482,6483,6489,6499],{},[27,6484,6485,6488],{},[31,6486,6487],{},"git commit",": save staged changes in local history",[27,6490,6491,6493,6494],{},[31,6492,4692],{},": commit message\n",[24,6495,6496],{},[27,6497,6498],{},"Message is required, even if empty",[27,6500,6501],{},"Baseline commit: starter state before custom work",[11,6503,6505,6509],{"id":6504,"level":14},"step-8-push",[16,6506,6508],{"id":6507},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[141,6510,6511,6519],{"gap":143,"left-width":144,"right-width":144},[146,6512,6513,6515],{"v-slot:left":148},[20,6514,151],{},[115,6516],{"language":118,"src":6517,"label":6518},"\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",[146,6520,6521,6523,6526],{"v-slot:right":148},[20,6522,6389],{},[115,6524],{"language":164,"src":6525,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[24,6527,6528,6532,6537,6542],{},[27,6529,6530,192],{},[31,6531,191],{},[27,6533,6534,6536],{},[31,6535,258],{},": remembers this branch's GitHub tracking branch",[27,6538,6539,6541],{},[31,6540,6086],{},": branch being sent",[27,6543,6544],{},"Refresh GitHub after the push",[11,6546,6548,6552],{"id":6547,"level":14},"step-9-open-pull-request",[16,6549,6551],{"id":6550},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[141,6553,6554,6597],{"gap":143,"left-width":144,"right-width":144},[146,6555,6556,6558],{"v-slot:left":148},[20,6557,3416],{},[24,6559,6560,6563,6579,6584,6589,6592],{},[27,6561,6562],{},"Open your course repository",[27,6564,951,6565,6568],{},[908,6566,6567],{},"Compare & pull request",[24,6569,6570],{},[27,6571,6572,6573,102,6576],{},"Or use ",[908,6574,6575],{},"Pull requests",[908,6577,6578],{},"New pull request",[27,6580,6581,6582],{},"Set base branch to ",[31,6583,67],{},[27,6585,6586,6587],{},"Set compare branch to ",[31,6588,6086],{},[27,6590,6591],{},"Confirm the changed files are the starter template files",[27,6593,951,6594],{},[908,6595,6596],{},"Create pull request",[146,6598,6599,6602,6606],{"v-slot:right":148},[20,6600,6601],{},"Use a short title and description:",[115,6603],{"language":164,"src":6604,"label":6605},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpull-request-description.txt","pull-request-description.txt",[24,6607,6608,6611,6614],{},[27,6609,6610],{},"Base receives the changes",[27,6612,6613],{},"Compare contains your branch work",[27,6615,6616],{},"If base and compare are reversed, do not create the pull request",[11,6618,6620,6626],{"id":6619,"level":14},"step-10-merge-sync-main",[16,6621,6623,6624],{"id":6622},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[31,6625,67],{},[141,6627,6628,6650],{"gap":143,"left-width":144,"right-width":144},[146,6629,6630,6632,6644,6646],{"v-slot:left":148},[20,6631,3416],{},[24,6633,6634,6639],{},[27,6635,951,6636],{},[908,6637,6638],{},"Merge pull request",[27,6640,951,6641],{},[908,6642,6643],{},"Confirm merge",[20,6645,5048],{},[115,6647],{"language":118,"src":6648,"label":6649},"\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",[146,6651,6652,6654,6657],{"v-slot:right":148},[20,6653,6389],{},[115,6655],{"language":164,"src":6656,"label":163},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[24,6658,6659,6664,6669],{},[27,6660,6661,6663],{},[31,6662,172],{},": return to the main branch",[27,6665,6666,6668],{},[31,6667,180],{},": download the merged template files",[27,6670,6671,6672,616],{},"Continue only when local ",[31,6673,67],{},[11,6675,6677,6683],{"id":6676,"level":14},"step-11-create-local-env",[16,6678,6679,6680],{"id":6676},"Step 11: Create Local ",[31,6681,6682],{},".env",[141,6684,6685,6707],{"gap":143,"left-width":144,"right-width":144},[146,6686,6687,6690,6694],{"v-slot:left":148},[20,6688,6689],{},"Run from the repository root:",[115,6691],{"language":118,"src":6692,"label":6693},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-11-create-local-env-11.sh","create-local-env.sh",[24,6695,6696],{},[27,6697,6698,6699,6702,6703],{},"Get ",[31,6700,6701],{},"DB_URL"," from ",[694,6704,6706],{"href":5555,"rel":6705},[698],"courses.ethereallab.app\u002Fdatabase",[146,6708,6709,6712,6717],{"v-slot:right":148},[20,6710,6711],{},"Fill in values similar to:",[115,6713],{"language":6714,"src":6715,"label":6716},"dotenv","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Flocal-env-example.txt","lib\u002F.env",[24,6718,6719,6724,6729,6732,6737,6742],{},[27,6720,6721,6723],{},[31,6722,6682],{}," stores local secrets",[27,6725,2479,6726,6728],{},[31,6727,6682],{}," on your computer only",[27,6730,6731],{},"Do not commit your real connection string",[27,6733,6734,6735],{},"Paste the generated database connection string as ",[31,6736,6701],{},[27,6738,6739,6741],{},[31,6740,6335],{}," loads local or hosted environment variables",[27,6743,6744,6745],{},"Do not paste secrets directly into ",[31,6746,6335],{},[11,6748,6750,6754],{"id":6749,"level":14},"step-12-test-local-db",[16,6751,6753],{"id":6752},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[141,6755,6756,6764],{"gap":143,"left-width":144,"right-width":144},[146,6757,6758,6760],{"v-slot:left":148},[20,6759,6689],{},[115,6761],{"language":118,"src":6762,"label":6763},"\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",[146,6765,6766,6769,6773],{"v-slot:right":148},[20,6767,6768],{},"Then open:",[115,6770],{"language":164,"src":6771,"label":6772},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Ftest-db-url.txt","browser-url.txt",[24,6774,6775,6781,6787,6795],{},[27,6776,6777,6780],{},[31,6778,6779],{},"php -S",": starts PHP's built-in local server",[27,6782,6783,6786],{},[31,6784,6785],{},"-t public_html",": serves the course web root",[27,6788,6789,6791,6792,6794],{},[31,6790,6316],{},": confirms PHP can read ",[31,6793,6682],{}," and connect to MySQL",[27,6796,6797,6798,6800],{},"Stop the server with ",[31,6799,2185],{}," when finished",[11,6802,6804,6812,6818],{"id":6803,"level":14},"step-13-enable-pdo-mysql",[16,6805,6807,6808,6811],{"id":6806},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[31,6809,6810],{},"pdo_mysql"," If Needed",[20,6813,6814,6815,1520],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[31,6816,6817],{},"apt",[141,6819,6820,6851],{"gap":143,"left-width":144,"right-width":144},[146,6821,6822,6825,6829,6832],{"v-slot:left":148},[20,6823,6824],{},"Find the PHP folder:",[115,6826],{"language":118,"src":6827,"label":6828},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-13-find-php-folder-13.sh","find-php-folder.sh",[20,6830,6831],{},"In that folder:",[24,6833,6834,6840,6846],{},[27,6835,6836,6837],{},"Find ",[31,6838,6839],{},"php.ini-development",[27,6841,6842,6843],{},"Copy it as ",[31,6844,6845],{},"php.ini",[27,6847,3799,6848,6850],{},[31,6849,6845],{}," in your editor",[146,6852,6853,6856,6860,6863,6867],{"v-slot:right":148},[20,6854,6855],{},"Uncomment these lines:",[115,6857],{"language":6858,"src":6859,"label":6845},"ini","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fphp-ini-pdo-mysql-settings.txt",[20,6861,6862],{},"Mac\u002FLinux usually use:",[115,6864],{"language":118,"src":6865,"label":6866},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fmacos-linux-pdo-mysql-commands-14.sh","macos-linux-php-mysql.sh",[24,6868,6869,6874],{},[27,6870,6871,6872],{},"Restart the php dev server after changing ",[31,6873,6845],{},[27,6875,6876],{},"Run Step 12 again after enabling the extension",[11,6878,6880,6882,6885],{"id":6879,"level":14},"quick-check-final",[16,6881,622],{"id":619},[20,6883,6884],{},"Confirm all of these:",[24,6886,6887,6890,6897,6900,6905,6914,6920,6925,6930,6936],{},[27,6888,6889],{},"GitHub shows the starter files",[27,6891,6892,6893,553,6895],{},"GitHub shows a pull request from ",[31,6894,6086],{},[31,6896,67],{},[27,6898,6899],{},"The pull request is merged",[27,6901,4818,6902,6904],{},[31,6903,67],{}," says the working tree is clean",[27,6906,6907,6296,6910,6913],{},[31,6908,6909],{},"public_html\u002Fm01",[31,6911,6912],{},"public_html\u002Fm10"," exist",[27,6915,6916,6919],{},[31,6917,6918],{},"public_html\u002Fproject"," exists",[27,6921,6922,6924],{},[31,6923,1587],{}," is not nested inside another accidental folder",[27,6926,6927,6929],{},[31,6928,6716],{}," exists locally and is not committed with real secrets",[27,6931,6932,6935],{},[31,6933,6934],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[27,6937,6938,6939,6941,6942,6944],{},"Windows PHP has ",[31,6940,6810],{}," enabled if ",[31,6943,6316],{}," reports a missing driver",[11,6946,6948,6952,6954,6957,6966],{"id":6947,"level":14},"reset-check",[16,6949,6951],{"id":6950},"if-something-looks-wrong","If Something Looks Wrong",[20,6953,151],{},[115,6955],{"language":118,"src":6956},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[6958,6959,6960],"blockquote",{},[20,6961,6962,6963,6965],{},"Tip: ",[31,6964,3953],{}," prints the repository root when your current folder is inside a Git repository",[24,6967,6968,6971,6974],{},[27,6969,6970],{},"Output should point to your course repository",[27,6972,6973],{},"If it points somewhere else, move folders before continuing",[27,6975,6976],{},"Avoid cloning inside another cloned repository",[11,6978,6979,6981],{"id":576,"level":14},[16,6980,579],{"id":576},[24,6982,6983,6986,6989,6994,6997,7000,7005,7015,7020,7023],{},[27,6984,6985],{},"Opening the parent folder instead of the repository root",[27,6987,6988],{},"Copying the instructor template folder as a nested folder",[27,6990,6991,6992,6222],{},"Copying the template ",[31,6993,6221],{},[27,6995,6996],{},"Keeping the downloaded ZIP inside the repository",[27,6998,6999],{},"Re-cloning the repository instead of opening the existing clone",[27,7001,7002,7003],{},"Putting module folders outside ",[31,7004,1587],{},[27,7006,7007,7008,7010,7011,7014],{},"Renaming ",[31,7009,6295],{}," to ",[31,7012,7013],{},"M1"," or mixing folder casing",[27,7016,7017,7018],{},"Doing template work directly on ",[31,7019,67],{},[27,7021,7022],{},"Reversing base and compare branches in the pull request",[27,7024,7025,7026,7028],{},"Forgetting to sync local ",[31,7027,67],{}," after the pull request is merged",[11,7030,7031,7033],{"id":660,"level":14},[16,7032,661],{"id":660},[24,7034,7035,7038,7041,7044,7047,7050],{},[27,7036,7037],{},"Repository root: top folder of the cloned project",[27,7039,7040],{},"Baseline: starter state before custom work begins",[27,7042,7043],{},"Pull request: GitHub review page used to merge branch work",[27,7045,7046],{},"Web root: folder served to the browser",[27,7048,7049],{},"Scaffold: starter folders that organize future work",[27,7051,7052],{},"Staging: choosing files for the next commit",[11,7054,7055,7057,7060],{"id":717,"level":14},[16,7056,720],{"id":717},[20,7058,7059],{},"Before leaving this presentation, confirm the following:",[24,7061,7062,7065,7068,7071,7077],{},[27,7063,7064],{},"You still have one clone for your repository",[27,7066,7067],{},"Your VS Code is able to open directly to your repository",[27,7069,7070],{},"Your repository has the full starter baseline correctly structured",[27,7072,7073,7074,7076],{},"GitHub remote ",[31,7075,67],{}," has the baseline content",[27,7078,4818,7079,7081],{},[31,7080,67],{}," was synchronized",{"title":148,"searchDepth":754,"depth":754,"links":7083},[7084,7085,7086,7087,7090,7093,7094,7095,7096,7097,7098,7100,7102,7103,7105,7106,7107,7108,7109],{"id":13,"depth":754,"text":18},{"id":6100,"depth":754,"text":6101},{"id":6142,"depth":754,"text":6143},{"id":6170,"depth":754,"text":6171,"children":7088},[7089],{"id":6203,"depth":1279,"text":6204},{"id":6234,"depth":754,"text":6235,"children":7091},[7092],{"id":6280,"depth":1279,"text":6281},{"id":6373,"depth":754,"text":6374},{"id":6417,"depth":754,"text":6418},{"id":6462,"depth":754,"text":6463},{"id":6507,"depth":754,"text":6508},{"id":6550,"depth":754,"text":6551},{"id":6622,"depth":754,"text":7099},"Step 10: Merge And Sync main",{"id":6676,"depth":754,"text":7101},"Step 11: Create Local .env",{"id":6752,"depth":754,"text":6753},{"id":6806,"depth":754,"text":7104},"Step 13: Enable pdo_mysql If Needed",{"id":619,"depth":754,"text":622},{"id":6950,"depth":754,"text":6951},{"id":576,"depth":754,"text":579},{"id":660,"depth":754,"text":661},{"id":717,"depth":754,"text":720},"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":6063,"description":7110},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[4338,146,793],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":4,"title":5,"audience":6,"body":7124,"contentType":775,"course":776,"description":777,"estimateBasis":778,"estimatedDiscussionMinutes":779,"estimatedLiveMinutes":780,"estimatedTotalMinutes":781,"extension":782,"meta":7683,"module":784,"navigation":785,"order":786,"path":787,"promptAssist":788,"seo":7684,"status":790,"stem":791,"tags":7685,"videoDuration":796,"videoId":797,"videoLink":798,"videoTitle":799,"week":784,"__hash__":800},{"type":8,"value":7125,"toc":7667},[7126,7154,7192,7208,7252,7300,7346,7386,7434,7468,7538,7570,7590,7637],[11,7127,7128,7130,7132],{"id":13,"level":14},[16,7129,18],{"id":13},[20,7131,22],{},[24,7133,7134,7140,7144,7148,7152],{},[27,7135,29,7136,34,7138],{},[31,7137,33],{},[31,7139,37],{},[27,7141,40,7142],{},[31,7143,33],{},[27,7145,40,7146],{},[31,7147,37],{},[27,7149,49,7150],{},[31,7151,33],{},[27,7153,54],{},[11,7155,7156,7158,7186],{"id":57,"level":14},[16,7157,60],{"id":57},[24,7159,7160,7168,7176,7184],{},[27,7161,7162,68,7164],{},[31,7163,67],{},[24,7165,7166],{},[27,7167,73],{},[27,7169,7170,78,7172],{},[31,7171,33],{},[24,7173,7174],{},[27,7175,83],{},[27,7177,7178,88,7180],{},[31,7179,37],{},[24,7181,7182],{},[27,7183,93],{},[27,7185,96],{},[20,7187,99,7188,102,7190],{},[31,7189,33],{},[31,7191,37],{},[11,7193,7194,7196,7198,7200],{"id":107,"level":14},[16,7195,110],{"id":107},[20,7197,113],{},[115,7199],{"label":117,"language":118,"src":119},[24,7201,7202,7204,7206],{},[27,7203,124],{},[27,7205,127],{},[27,7207,130],{},[11,7209,7210,7214],{"id":133,"level":14},[16,7211,137,7212],{"id":136},[31,7213,67],{},[141,7215,7216,7222],{"gap":143,"left-width":144,"right-width":144},[146,7217,7218,7220],{"v-slot:left":148},[20,7219,151],{},[115,7221],{"label":154,"language":118,"src":155},[146,7223,7224,7226,7228],{"v-slot:right":148},[20,7225,160],{},[115,7227],{"label":163,"language":164,"src":165},[24,7229,7230,7236],{},[27,7231,7232,173,7234],{},[31,7233,172],{},[31,7235,67],{},[27,7237,7238,181,7240,184,7242],{},[31,7239,180],{},[31,7241,67],{},[24,7243,7244,7248],{},[27,7245,7246,192],{},[31,7247,191],{},[27,7249,7250,197],{},[31,7251,67],{},[11,7253,7254,7258],{"id":200,"level":14},[16,7255,204,7256],{"id":203},[31,7257,33],{},[141,7259,7260,7266],{"gap":143,"left-width":144,"right-width":144},[146,7261,7262,7264],{"v-slot:left":148},[20,7263,151],{},[115,7265],{"label":215,"language":118,"src":216},[146,7267,7268,7270,7272],{"v-slot:right":148},[20,7269,160],{},[115,7271],{"label":163,"language":164,"src":223},[24,7273,7274,7286],{},[27,7275,7276,231,7278,234,7280],{},[31,7277,230],{},[31,7279,33],{},[24,7281,7282],{},[27,7283,7284,242],{},[31,7285,241],{},[27,7287,7288,248,7290,251,7292],{},[31,7289,247],{},[31,7291,33],{},[24,7293,7294],{},[27,7295,7296,259,7298,263],{},[31,7297,258],{},[31,7299,262],{},[11,7301,7302,7306],{"id":266,"level":14},[16,7303,270,7304],{"id":269},[31,7305,37],{},[141,7307,7308,7314],{"gap":143,"left-width":144,"right-width":144},[146,7309,7310,7312],{"v-slot:left":148},[20,7311,151],{},[115,7313],{"label":281,"language":118,"src":282},[146,7315,7316,7318,7320],{"v-slot:right":148},[20,7317,160],{},[115,7319],{"label":163,"language":164,"src":289},[24,7321,7322,7328,7332,7342],{},[27,7323,294,7324,297,7326,300],{},[31,7325,37],{},[31,7327,33],{},[27,7329,7330],{},[31,7331,305],{},[27,7333,308,7334,251,7336],{},[31,7335,37],{},[24,7337,7338],{},[27,7339,7340],{},[31,7341,317],{},[27,7343,7344,322],{},[31,7345,37],{},[11,7347,7348,7352],{"id":325,"level":14},[16,7349,328,7350],{"id":325},[31,7351,33],{},[141,7353,7354,7360],{"gap":143,"left-width":144,"right-width":144},[146,7355,7356,7358],{"v-slot:left":148},[20,7357,151],{},[115,7359],{"label":339,"language":118,"src":340},[146,7361,7362,7364,7366],{"v-slot:right":148},[20,7363,160],{},[115,7365],{"label":163,"language":164,"src":347},[24,7367,7368,7372,7376],{},[27,7369,7370,354],{},[31,7371,33],{},[27,7373,7374,359],{},[31,7375,37],{},[27,7377,362,7378,7380],{},[31,7379,37],{},[24,7381,7382],{},[27,7383,369,7384,372],{},[31,7385,37],{},[11,7387,7388,7392],{"id":375,"level":14},[16,7389,379,7390],{"id":378},[31,7391,37],{},[141,7393,7394,7400],{"gap":143,"left-width":144,"right-width":144},[146,7395,7396,7398],{"v-slot:left":148},[20,7397,151],{},[115,7399],{"label":390,"language":118,"src":391},[146,7401,7402,7404,7406],{"v-slot:right":148},[20,7403,160],{},[115,7405],{"label":163,"language":164,"src":398},[24,7407,7408,7424],{},[27,7409,7410,406,7412,7414],{},[31,7411,405],{},[31,7413,37],{},[24,7415,7416,7420],{},[27,7417,7418,416],{},[31,7419,415],{},[27,7421,7422,422],{},[31,7423,421],{},[27,7425,7426,428,7428],{},[31,7427,427],{},[24,7429,7430],{},[27,7431,433,7432,437],{},[31,7433,436],{},[11,7435,7436,7438,7440,7442,7456,7458],{"id":440,"level":14},[16,7437,443],{"id":440},[20,7439,446],{},[20,7441,449],{},[24,7443,7444,7448,7452],{},[27,7445,7446],{},[31,7447,67],{},[27,7449,7450],{},[31,7451,33],{},[27,7453,7454],{},[31,7455,37],{},[20,7457,466],{},[24,7459,7460,7464],{},[27,7461,7462,473],{},[31,7463,33],{},[27,7465,7466,478],{},[31,7467,37],{},[11,7469,7470,7472],{"id":481,"level":14},[16,7471,485],{"id":484},[487,7473,7474,7488,7494,7502,7506,7516,7518,7524,7534],{},[27,7475,491,7476,7478],{},[31,7477,33],{},[24,7479,7480,7484],{},[27,7481,7482],{},[31,7483,500],{},[27,7485,7486],{},[31,7487,505],{},[27,7489,508,7490],{},[24,7491,7492],{},[27,7493,513],{},[27,7495,516,7496],{},[24,7497,7498],{},[27,7499,521,7500,525],{},[31,7501,524],{},[27,7503,528,7504],{},[31,7505,33],{},[27,7507,533,7508,536,7510],{},[31,7509,33],{},[24,7511,7512],{},[27,7513,541,7514,544],{},[31,7515,33],{},[27,7517,547],{},[27,7519,550,7520,553,7522],{},[31,7521,33],{},[31,7523,37],{},[27,7525,533,7526,560,7528],{},[31,7527,37],{},[24,7529,7530],{},[27,7531,565,7532,544],{},[31,7533,37],{},[27,7535,570,7536,573],{},[31,7537,33],{},[11,7539,7540,7542],{"id":576,"level":14},[16,7541,579],{"id":576},[24,7543,7544,7548,7552,7558,7564,7566],{},[27,7545,584,7546],{},[31,7547,37],{},[27,7549,589,7550],{},[31,7551,33],{},[27,7553,594,7554,597,7556],{},[31,7555,33],{},[31,7557,37],{},[27,7559,602,7560,605,7562],{},[31,7561,37],{},[31,7563,37],{},[27,7565,610],{},[27,7567,613,7568,616],{},[31,7569,524],{},[11,7571,7572,7574,7576],{"id":619,"level":14},[16,7573,622],{"id":619},[20,7575,625],{},[24,7577,7578,7580,7582,7584,7588],{},[27,7579,630],{},[27,7581,633],{},[27,7583,636],{},[27,7585,639,7586,642],{},[31,7587,37],{},[27,7589,645],{},[11,7591,7592,7594],{"id":648,"level":14},[16,7593,652],{"id":651},[141,7595,7596,7616],{"gap":143,"left-width":144,"right-width":144},[146,7597,7598,7600],{"v-slot:left":148},[658,7599,661],{"id":660},[24,7601,7602,7604,7606,7610,7614],{},[27,7603,666],{},[27,7605,669],{},[27,7607,7608,674],{},[31,7609,33],{},[27,7611,7612,679],{},[31,7613,37],{},[27,7615,682],{},[146,7617,7618,7620],{"v-slot:right":148},[658,7619,687],{"id":648},[24,7621,7622,7627,7632],{},[27,7623,692,7624],{},[694,7625,699],{"href":696,"rel":7626},[698],[27,7628,692,7629],{},[694,7630,706],{"href":704,"rel":7631},[698],[27,7633,709,7634],{},[694,7635,714],{"href":712,"rel":7636},[698],[11,7638,7639,7641,7643],{"id":717,"level":14},[16,7640,720],{"id":717},[20,7642,723],{},[24,7644,7645,7653,7657,7661,7665],{},[27,7646,728,7647,731,7649,734,7651],{},[31,7648,67],{},[31,7650,33],{},[31,7652,37],{},[27,7654,40,7655],{},[31,7656,33],{},[27,7658,40,7659],{},[31,7660,37],{},[27,7662,747,7663],{},[31,7664,33],{},[27,7666,752],{},{"title":148,"searchDepth":754,"depth":754,"links":7668},[7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7681,7682],{"id":13,"depth":754,"text":18},{"id":57,"depth":754,"text":60},{"id":107,"depth":754,"text":110},{"id":136,"depth":754,"text":760},{"id":203,"depth":754,"text":762},{"id":269,"depth":754,"text":764},{"id":325,"depth":754,"text":766},{"id":378,"depth":754,"text":768},{"id":440,"depth":754,"text":443},{"id":484,"depth":754,"text":485},{"id":576,"depth":754,"text":579},{"id":619,"depth":754,"text":622},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},{},{"title":5,"description":777},[793,794,33,795],{"id":7687,"title":7688,"audience":6,"body":7689,"contentType":775,"course":776,"description":8496,"estimateBasis":8497,"estimatedDiscussionMinutes":779,"estimatedLiveMinutes":781,"estimatedTotalMinutes":786,"extension":782,"meta":8498,"module":784,"navigation":785,"order":8499,"path":8500,"promptAssist":788,"seo":8501,"status":790,"stem":8502,"tags":8503,"videoDuration":8506,"videoId":8507,"videoLink":8508,"videoTitle":8509,"week":784,"__hash__":8510},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7690,"toc":8475},[7691,7718,7741,7770,7838,7899,7934,7970,8007,8057,8103,8138,8184,8221,8249,8281,8328,8361,8429],[11,7692,7694,7697],{"id":7693,"level":14},"render-setup-title",[16,7695,7688],{"id":7696},"render-setup",[24,7698,7699,7702,7707,7712,7715],{},[27,7700,7701],{},"Connect GitHub repo to Render",[27,7703,7704,7705],{},"Create a QA service from ",[31,7706,33],{},[27,7708,7709,7710],{},"Create a production service from ",[31,7711,37],{},[27,7713,7714],{},"Add the course database connection string",[27,7716,7717],{},"Verify live URLs and deploy logs",[11,7719,7720,7722,7724],{"id":3259,"level":14},[16,7721,3262],{"id":3259},[20,7723,22],{},[24,7725,7726,7729,7732,7735,7738],{},[27,7727,7728],{},"Explain what Render does in the course workflow",[27,7730,7731],{},"Create separate QA and production services",[27,7733,7734],{},"Connect each service to the correct branch",[27,7736,7737],{},"Read Render logs when a deploy fails",[27,7739,7740],{},"Identify which deployed URL to submit or test",[11,7742,7744,7747,7764],{"id":7743,"level":14},"what-render-does",[16,7745,7746],{"id":7743},"What Render Does",[24,7748,7749,7752,7755,7758,7761],{},[27,7750,7751],{},"Hosts your PHP app from GitHub",[27,7753,7754],{},"Watches a selected branch",[27,7756,7757],{},"Rebuilds when that branch changes",[27,7759,7760],{},"Stores secrets as environment variables",[27,7762,7763],{},"Gives each service a public URL",[20,7765,7766,7767],{},"Course loop: ",[31,7768,7769],{},"local work -> GitHub branch -> Render URL",[11,7771,7773,7775],{"id":7772,"level":14},"free-tier-and-before-start",[16,7774,110],{"id":107},[141,7776,7777,7806],{"gap":143,"left-width":144,"right-width":144},[146,7778,7779,7783],{"v-slot:left":148},[658,7780,7782],{"id":7781},"free-tier","Free Tier",[24,7784,7785,7795,7803],{},[27,7786,3426,7787,7790],{},[31,7788,7789],{},"Free",[24,7791,7792],{},[27,7793,7794],{},"Render may default to a paid plan",[27,7796,7797,7798],{},"Free services can sleep",[24,7799,7800],{},[27,7801,7802],{},"First visit after sleep may be slow",[27,7804,7805],{},"Avoid extra services unless instructed",[146,7807,7808,7812],{"v-slot:right":148},[658,7809,7811],{"id":7810},"repo-ready","Repo Ready",[24,7813,7814,7817,7822,7831],{},[27,7815,7816],{},"Starter files committed and pushed",[27,7818,7819,7821],{},[31,7820,6354],{}," in repo root",[27,7823,7824,731,7826,734,7828,7830],{},[31,7825,1587],{},[31,7827,6262],{},[31,7829,6265],{}," present",[27,7832,7833,34,7835,7837],{},[31,7834,33],{},[31,7836,37],{}," branches exist on GitHub",[11,7839,7841,7844],{"id":7840,"level":14},"target-architecture",[16,7842,7843],{"id":7840},"Target Architecture",[141,7845,7846,7874],{"gap":143,"left-width":144,"right-width":144},[146,7847,7848,7852],{"v-slot:left":148},[658,7849,7851],{"id":7850},"qa-service","QA Service",[24,7853,7854,7860,7865,7868],{},[27,7855,7856,7857],{},"Name: ",[31,7858,7859],{},"\u003Cucid>-it202-\u003Csection>-qa",[27,7861,7862,7863],{},"Watches ",[31,7864,33],{},[27,7866,7867],{},"Used for testing and evidence",[27,7869,7870,7871],{},"URL ends with ",[31,7872,7873],{},"-qa.onrender.com",[146,7875,7876,7880],{"v-slot:right":148},[658,7877,7879],{"id":7878},"production-service","Production Service",[24,7881,7882,7887,7891,7894],{},[27,7883,7856,7884],{},[31,7885,7886],{},"\u003Cucid>-it202-\u003Csection>-prod",[27,7888,7862,7889],{},[31,7890,37],{},[27,7892,7893],{},"Stable version after QA checks",[27,7895,7870,7896],{},[31,7897,7898],{},"-prod.onrender.com",[11,7900,7902,7906],{"id":7901,"level":14},"step-1-sign-up",[16,7903,7905],{"id":7904},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[141,7907,7908,7926],{"gap":143,"left-width":2963,"right-width":2962},[146,7909,7910],{"v-slot:left":148},[24,7911,7912,7917,7920,7923],{},[27,7913,2434,7914],{},[31,7915,7916],{},"render.com",[27,7918,7919],{},"Choose GitHub sign-in",[27,7921,7922],{},"Authorize Render when prompted",[27,7924,7925],{},"Land on the Render dashboard",[146,7927,7928],{"v-slot:right":148},[20,7929,7930],{},[926,7931],{"alt":7932,"src":7933,"variant":930},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,7935,7937,7940],{"id":7936,"level":14},"step-2-new-web-service",[16,7938,7939],{"id":7936},"Step 2: New Web Service",[141,7941,7942,7962],{"gap":143,"left-width":2963,"right-width":2962},[146,7943,7944],{"v-slot:left":148},[24,7945,7946,7951,7956,7959],{},[27,7947,951,7948],{},[31,7949,7950],{},"New +",[27,7952,3426,7953],{},[31,7954,7955],{},"Web Service",[27,7957,7958],{},"Do not choose a database service here",[27,7960,7961],{},"This creates the hosted PHP app",[146,7963,7964],{"v-slot:right":148},[20,7965,7966],{},[926,7967],{"alt":7968,"src":7969,"variant":930},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,7971,7973,7977],{"id":7972,"level":14},"step-3-connect-repo",[16,7974,7976],{"id":7975},"step-3-connect-repository","Step 3: Connect Repository",[141,7978,7979,7999],{"gap":143,"left-width":2460,"right-width":3003},[146,7980,7981],{"v-slot:left":148},[24,7982,7983,7986,7989,7996],{},[27,7984,7985],{},"Select your student course repository",[27,7987,7988],{},"Authorize repository access if Render asks",[27,7990,7991,7992,7995],{},"Ensure it's the proper repository (format: ",[31,7993,7994],{},"ucid-course-section-semYear",")",[27,7997,7998],{},"Continue to service settings",[146,8000,8001],{"v-slot:right":148},[20,8002,8003],{},[926,8004],{"alt":8005,"src":8006,"variant":930},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,8008,8010,8014],{"id":8009,"level":14},"step-4-configure-qa",[16,8011,8013],{"id":8012},"step-4-configure-qa-service","Step 4: Configure QA Service",[141,8015,8016,8049],{"gap":143,"left-width":2963,"right-width":2962},[146,8017,8018,8021],{"v-slot:left":148},[20,8019,8020],{},"Use these settings:",[24,8022,8023,8027,8032,8038,8043,8046],{},[27,8024,7856,8025],{},[31,8026,7859],{},[27,8028,8029,8030],{},"Branch: ",[31,8031,33],{},[27,8033,8034,8035],{},"Runtime: ",[31,8036,8037],{},"Docker",[27,8039,8040,8041],{},"Instance type: ",[31,8042,7789],{},[27,8044,8045],{},"Root directory: blank",[27,8047,8048],{},"Build\u002Fstart commands: blank",[146,8050,8051],{"v-slot:right":148},[20,8052,8053],{},[926,8054],{"alt":8055,"src":8056,"variant":930},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,8058,8060,8064],{"id":8059,"level":14},"step-5-env-vars",[16,8061,8063],{"id":8062},"step-5-add-environment-variables","Step 5: Add Environment Variables",[141,8065,8066,8095],{"gap":143,"left-width":3411,"right-width":5587},[146,8067,8068],{"v-slot:left":148},[24,8069,8070,8083,8089,8092],{},[27,8071,8072,8073,8075],{},"Add ",[31,8074,6701],{},[24,8076,8077],{},[27,8078,8079,8080],{},"Get it from ",[694,8081,6706],{"href":5555,"rel":8082},[698],[27,8084,8085,8086,8088],{},"Do not use \"add from ",[31,8087,6682],{},"\"",[27,8090,8091],{},"Add later API keys only when a later lesson requires them",[27,8093,8094],{},"Repeat required env vars on both QA and production",[146,8096,8097],{"v-slot:right":148},[20,8098,8099],{},[926,8100],{"alt":8101,"src":8102,"variant":930},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,8104,8106,8109],{"id":8105,"level":14},"step-6-deploy-qa",[16,8107,8108],{"id":8105},"Step 6: Deploy QA",[141,8110,8111,8130],{"gap":143,"left-width":2460,"right-width":3003},[146,8112,8113],{"v-slot:left":148},[24,8114,8115,8118,8121,8124,8127],{},[27,8116,8117],{},"Create the QA service",[27,8119,8120],{},"Watch the first deploy log",[27,8122,8123],{},"Wait for a success state",[27,8125,8126],{},"Open the QA URL",[27,8128,8129],{},"Confirm the starter page loads",[146,8131,8132],{"v-slot:right":148},[20,8133,8134],{},[926,8135],{"alt":8136,"src":8137,"variant":930},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,8139,8141,8145],{"id":8140,"level":14},"step-7-create-prod",[16,8142,8144],{"id":8143},"step-7-create-production-service","Step 7: Create Production Service",[141,8146,8147,8176],{"gap":143,"left-width":2963,"right-width":2962},[146,8148,8149,8152],{"v-slot:left":148},[20,8150,8151],{},"Create a second web service:",[24,8153,8154,8157,8161,8165,8169,8173],{},[27,8155,8156],{},"Same repository",[27,8158,7856,8159],{},[31,8160,7886],{},[27,8162,8029,8163],{},[31,8164,37],{},[27,8166,8034,8167],{},[31,8168,8037],{},[27,8170,8040,8171],{},[31,8172,7789],{},[27,8174,8175],{},"Same required env vars",[146,8177,8178],{"v-slot:right":148},[20,8179,8180],{},[926,8181],{"alt":8182,"src":8183,"variant":930},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,8185,8186,8189],{"id":481,"level":14},[16,8187,8188],{"id":481},"Normal Workflow",[487,8190,8191,8194,8197,8202,8205,8208,8211,8218],{},[27,8192,8193],{},"Work locally on a feature or homework branch",[27,8195,8196],{},"Commit and push that branch to GitHub",[27,8198,8199,8200],{},"Open a pull request into ",[31,8201,33],{},[27,8203,8204],{},"Merge after review",[27,8206,8207],{},"Render updates the QA URL",[27,8209,8210],{},"Test the QA URL",[27,8212,550,8213,553,8215,8217],{},[31,8214,33],{},[31,8216,37],{}," after evidence gathering",[27,8219,8220],{},"Render updates the production URL",[11,8222,8224,8227],{"id":8223,"level":14},"urls-and-cold-starts",[16,8225,8226],{"id":8223},"URLs And Cold Starts",[24,8228,8229,8232,8235,8238,8246],{},[27,8230,8231],{},"QA URL shows the test deployment",[27,8233,8234],{},"Production URL shows the stable deployment",[27,8236,8237],{},"Homework evidence usually starts with QA",[27,8239,8240,8241],{},"Free services may sleep after inactivity\n",[24,8242,8243],{},[27,8244,8245],{},"First visit after sleep may take extra time (2 - 5 minutes)",[27,8247,8248],{},"Do not submit before Render finishes deploying",[11,8250,8252,8255],{"id":8251,"level":14},"logs-and-status",[16,8253,8254],{"id":8251},"Logs And Status",[141,8256,8257,8273],{"gap":143,"left-width":2460,"right-width":3003},[146,8258,8259],{"v-slot:left":148},[24,8260,8261,8264,8267,8270],{},[27,8262,8263],{},"Logs show build and startup output",[27,8265,8266],{},"Dashboard status shows deploy progress",[27,8268,8269],{},"Failed deploys usually show the first useful clue",[27,8271,8272],{},"Read the first clear error before changing settings",[146,8274,8275],{"v-slot:right":148},[20,8276,8277],{},[926,8278],{"alt":8279,"src":8280,"variant":930},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8282,8284,8287],{"id":8283,"level":14},"troubleshooting",[16,8285,8286],{"id":8283},"Troubleshooting",[24,8288,8289,8299,8307,8317],{},[27,8290,8291,8292],{},"Build fails\n",[24,8293,8294],{},[27,8295,521,8296,8298],{},[31,8297,6354],{},", root directory, runtime, and instance type",[27,8300,8301,8302],{},"App deploys but page fails\n",[24,8303,8304],{},[27,8305,8306],{},"Check logs for PHP errors",[27,8308,8309,8310],{},"Database connection fails\n",[24,8311,8312],{},[27,8313,521,8314,8316],{},[31,8315,6701],{}," spelling and copied value",[27,8318,8319,8320],{},"Wrong version appears\n",[24,8321,8322,8325],{},[27,8323,8324],{},"Confirm the service watches the expected branch",[27,8326,8327],{},"Clear browser cache or test in a private window",[11,8329,8330,8332],{"id":576,"level":14},[16,8331,579],{"id":576},[24,8333,8334,8344,8347,8352,8355,8358],{},[27,8335,8336,8337,8339,8340,1961,8342],{},"Choosing ",[31,8338,67],{}," instead of ",[31,8341,33],{},[31,8343,37],{},[27,8345,8346],{},"Creating one service for both environments",[27,8348,8349,8350],{},"Forgetting ",[31,8351,6701],{},[27,8353,8354],{},"Using a paid instance type by accident",[27,8356,8357],{},"Checking GitHub but not the Render URL",[27,8359,8360],{},"Changing code locally but forgetting to push and merge",[11,8362,8363,8365],{"id":651,"level":14},[16,8364,652],{"id":651},[141,8366,8367,8395],{"gap":143,"left-width":144,"right-width":144},[146,8368,8369,8371,8377,8383,8389],{"v-slot:left":148},[658,8370,661],{"id":660},[20,8372,8373,8376],{},[908,8374,8375],{},"Service"," - one deployed app on Render",[20,8378,8379,8382],{},[908,8380,8381],{},"Watched branch"," - Git branch Render deploys from",[20,8384,8385,8388],{},[908,8386,8387],{},"Environment variable"," - setting stored outside code",[20,8390,8391,8394],{},[908,8392,8393],{},"Deploy log"," - output from Render's build\u002Fstart process",[146,8396,8397,8399],{"v-slot:right":148},[658,8398,687],{"id":648},[24,8400,8401,8408,8415,8422],{},[27,8402,8403],{},[694,8404,8407],{"href":8405,"rel":8406},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[698],"Render Docs: Web Services",[27,8409,8410],{},[694,8411,8414],{"href":8412,"rel":8413},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[698],"Render Docs: Deploys",[27,8416,8417],{},[694,8418,8421],{"href":8419,"rel":8420},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[698],"Render Docs: Environment Variables",[27,8423,8424],{},[694,8425,8428],{"href":8426,"rel":8427},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[698],"Render Docs: Free Instance Types",[11,8430,8431,8433,8436],{"id":717,"level":14},[16,8432,720],{"id":717},[20,8434,8435],{},"Before leaving this presentation, confirm you:",[24,8437,8438,8441,8444,8451,8454,8457],{},[27,8439,8440],{},"Created QA and production Render services",[27,8442,8443],{},"Matched each service to the correct branch",[27,8445,8446,8447,6702,8449],{},"Added ",[31,8448,6701],{},[31,8450,6706],{},[27,8452,8453],{},"Opened each deployed URL",[27,8455,8456],{},"Read logs instead of assuming it worked",[27,8458,8459,8460],{},"Understand the local -> GitHub -> Render loop\n",[24,8461,8462,8465,8470],{},[27,8463,8464],{},"Majority of your work will be done locally and tested locally",[27,8466,8467,8469],{},[31,8468,33],{}," is just for gathering evidence for submissions",[27,8471,8472,8474],{},[31,8473,37],{}," is what will be verified during grading",{"title":148,"searchDepth":754,"depth":754,"links":8476},[8477,8478,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495],{"id":7696,"depth":754,"text":7688},{"id":3259,"depth":754,"text":3262},{"id":7743,"depth":754,"text":7746},{"id":107,"depth":754,"text":110},{"id":7840,"depth":754,"text":7843},{"id":7904,"depth":754,"text":7905},{"id":7936,"depth":754,"text":7939},{"id":7975,"depth":754,"text":7976},{"id":8012,"depth":754,"text":8013},{"id":8062,"depth":754,"text":8063},{"id":8105,"depth":754,"text":8108},{"id":8143,"depth":754,"text":8144},{"id":481,"depth":754,"text":8188},{"id":8223,"depth":754,"text":8226},{"id":8251,"depth":754,"text":8254},{"id":8283,"depth":754,"text":8286},{"id":576,"depth":754,"text":579},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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":7688,"description":8496},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8504,8505,33,795],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8512,"title":8513,"audience":6,"body":8514,"contentType":775,"course":776,"description":11188,"estimateBasis":11189,"estimatedDiscussionMinutes":11190,"estimatedLiveMinutes":11191,"estimatedTotalMinutes":11192,"extension":782,"meta":11193,"module":784,"navigation":785,"order":5260,"path":11194,"promptAssist":788,"seo":11195,"status":790,"stem":11196,"tags":11197,"videoDuration":11202,"videoId":11203,"videoLink":11204,"videoTitle":11205,"week":784,"__hash__":11206},"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":8515,"toc":11120},[8516,8545,8590,8626,8695,8727,8754,8786,8812,8841,8870,8897,8928,8956,8992,9057,9092,9138,9181,9225,9272,9335,9371,9406,9443,9476,9513,9546,9576,9606,9636,9666,9696,9730,9762,9794,9826,9875,9877,9920,9946,9987,10039,10118,10169,10200,10230,10260,10310,10335,10385,10433,10491,10549,10590,10620,10654,10688,10722,10773,10825,10844,10872,10920,10992,11092],[11,8517,8519,8522],{"id":8518,"level":14},"virtualbox-title",[16,8520,8513],{"id":8521},"local-ubuntu-web-server-with-virtualbox",[24,8523,8524,8527,8530,8533,8536,8542],{},[27,8525,8526],{},"Primary course path for the local Ubuntu VM",[27,8528,8529],{},"Create an Ubuntu Server VM in VirtualBox",[27,8531,8532],{},"Connect from your host terminal with SSH",[27,8534,8535],{},"Share the course repo into Ubuntu",[27,8537,8538,8539,8541],{},"Serve ",[31,8540,1587],{}," through Apache and PHP",[27,8543,8544],{},"Create a local MySQL database for testing",[11,8546,8548,8551,8554,8565,8568],{"id":8547,"level":14},"main-goal",[16,8549,8550],{"id":8547},"Main Goal",[20,8552,8553],{},"Your host computer and Ubuntu VM have different jobs:",[24,8555,8556,8559,8562],{},[27,8557,8558],{},"Host computer: edit files with VS Code and open the browser",[27,8560,8561],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[27,8563,8564],{},"Shared folder: lets both use the same course repo files",[20,8566,8567],{},"Target result:",[24,8569,8570,8576,8581,8584,8587],{},[27,8571,8572,8573],{},"Host browser opens ",[31,8574,8575],{},"http:\u002F\u002Flocalhost:3000",[27,8577,8578,8579],{},"Apache serves the repo's ",[31,8580,1587],{},[27,8582,8583],{},"PHP executes inside Ubuntu",[27,8585,8586],{},"Local MySQL has a database and user named after your UCID",[27,8588,8589],{},"Edits made on the host appear after browser refresh",[11,8591,8593,8596,8599,8618,8621],{"id":8592,"level":14},"virtualbox-caveat",[16,8594,8595],{"id":8592},"VirtualBox Caveat",[20,8597,8598],{},"VirtualBox is the primary local VM path for this course:",[24,8600,8601,8604,8607,8615],{},[27,8602,8603],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[27,8605,8606],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[27,8608,8609,8610],{},"Windows on Arm support is experimental in VirtualBox\n",[24,8611,8612],{},[27,8613,8614],{},"Avoid unless your instructor confirms it for your machine",[27,8616,8617],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[20,8619,8620],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[2675,8622,8623],{"type":3947},[20,8624,8625],{},"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,8627,8628,8630],{"id":107,"level":14},[16,8629,110],{"id":107},[24,8631,8632,8650,8668,8671,8674,8677,8692],{},[27,8633,8634,8635],{},"VirtualBox downloaded\n",[24,8636,8637,8644,8647],{},[27,8638,8639],{},[694,8640,8643],{"href":8641,"rel":8642},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[698],"VirtualBox downloads",[27,8645,8646],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[27,8648,8649],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[27,8651,8652,8653],{},"Ubuntu Server ISO downloaded\n",[24,8654,8655,8662,8665],{},[27,8656,8657],{},[694,8658,8661],{"href":8659,"rel":8660},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[698],"Ubuntu Server installer",[27,8663,8664],{},"Apple Silicon Mac: use the ARM64 server ISO",[27,8666,8667],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[27,8669,8670],{},"Internet Applications course repo cloned on host computer",[27,8672,8673],{},"Git\u002FGitHub setup already working",[27,8675,8676],{},"Administrator access on your computer",[27,8678,8679,8680,8683,8684],{},"At least ",[31,8681,8682],{},"10 GB"," free disk space for the VM\n",[24,8685,8686],{},[27,8687,8688,8691],{},[31,8689,8690],{},"20-25 GB"," is safer if your computer has room",[27,8693,8694],{},"Stable internet for package installs",[11,8696,8698,8701],{"id":8697,"level":14},"setup-parts",[16,8699,8700],{"id":8697},"Setup Parts",[24,8702,8703,8706,8709,8712,8718,8721,8724],{},[27,8704,8705],{},"VM: Ubuntu Server running inside VirtualBox",[27,8707,8708],{},"NAT adapter: gives the VM internet access",[27,8710,8711],{},"Port forwarding: lets the host reach SSH and Apache",[27,8713,8714,8715],{},"SSH: lets the host terminal control Ubuntu through ",[31,8716,8717],{},"localhost",[27,8719,8720],{},"Shared folder: exposes the host repo inside Ubuntu",[27,8722,8723],{},"Apache\u002FPHP: serves and executes the web app",[27,8725,8726],{},"MySQL: local database server for local testing",[11,8728,8730,8734],{"id":8729,"level":14},"install-virtualbox-windows",[16,8731,8733],{"id":8732},"install-virtualbox-on-windows","Install VirtualBox On Windows",[24,8735,8736,8739,8742,8745,8748,8751],{},[27,8737,8738],{},"Download VirtualBox for Windows hosts",[27,8740,8741],{},"Run the installer as an administrator if prompted",[27,8743,8744],{},"Keep the default install path and features",[27,8746,8747],{},"Accept the network reset warning",[27,8749,8750],{},"Open VirtualBox after installation",[27,8752,8753],{},"See the slides below for the Windows installer screens",[11,8755,8757,8760],{"id":8756,"level":886},"windows-installer-start",[16,8758,8759],{"id":8756},"Windows Installer: Start",[141,8761,8762,8770],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8763,8764],{"v-slot:left":148},[20,8765,8766],{},[926,8767],{"alt":8768,"src":8769,"variant":930},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[146,8771,8772],{"v-slot:right":148},[24,8773,8774,8780,8783],{},[27,8775,8776,8777],{},"Launch the downloaded ",[31,8778,8779],{},".exe",[27,8781,8782],{},"Approve the Windows security prompt if shown",[27,8784,8785],{},"Start the setup wizard",[11,8787,8789,8792],{"id":8788,"level":886},"windows-installer-features",[16,8790,8791],{"id":8788},"Windows Installer: Features",[141,8793,8794,8802],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8795,8796],{"v-slot:left":148},[20,8797,8798],{},[926,8799],{"alt":8800,"src":8801,"variant":930},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[146,8803,8804],{"v-slot:right":148},[24,8805,8806,8809],{},[27,8807,8808],{},"Keep the default install location",[27,8810,8811],{},"Keep the default features selected",[11,8813,8815,8818],{"id":8814,"level":886},"windows-installer-network-warning",[16,8816,8817],{"id":8814},"Windows Installer: Network Warning",[141,8819,8820,8828],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8821,8822],{"v-slot:left":148},[20,8823,8824],{},[926,8825],{"alt":8826,"src":8827,"variant":930},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[146,8829,8830],{"v-slot:right":148},[24,8831,8832,8835,8838],{},[27,8833,8834],{},"VirtualBox may reset network adapters briefly",[27,8836,8837],{},"This is expected during install",[27,8839,8840],{},"Save web work before continuing if needed",[11,8842,8844,8847],{"id":8843,"level":886},"windows-installer-ready",[16,8845,8846],{"id":8843},"Windows Installer: Ready",[141,8848,8849,8857],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8850,8851],{"v-slot:left":148},[20,8852,8853],{},[926,8854],{"alt":8855,"src":8856,"variant":930},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[146,8858,8859],{"v-slot:right":148},[24,8860,8861,8864,8867],{},[27,8862,8863],{},"Start the installation",[27,8865,8866],{},"Keep the default choices",[27,8868,8869],{},"Wait for the installer to request permissions if needed",[11,8871,8873,8877],{"id":8872,"level":886},"windows-installer-progress",[16,8874,8876],{"id":8875},"windows-installer-start-options","Windows Installer: Start Options",[141,8878,8879,8887],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8880,8881],{"v-slot:left":148},[20,8882,8883],{},[926,8884],{"alt":8885,"src":8886,"variant":930},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[146,8888,8889],{"v-slot:right":148},[24,8890,8891,8894],{},[27,8892,8893],{},"No need to create a Start Menu item or desktop shortcut unless desired",[27,8895,8896],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,8898,8900,8903],{"id":8899,"level":886},"windows-installer-permission",[16,8901,8902],{"id":8899},"Windows Installer: Permission",[141,8904,8905,8913],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8906,8907],{"v-slot:left":148},[20,8908,8909],{},[926,8910],{"alt":8911,"src":8912,"variant":930},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[146,8914,8915],{"v-slot:right":148},[24,8916,8917,8920],{},[27,8918,8919],{},"Proceed with install",[27,8921,8922,8923],{},"Approve VirtualBox driver prompts\n",[24,8924,8925],{},[27,8926,8927],{},"These let VirtualBox create virtual hardware",[11,8929,8931,8934],{"id":8930,"level":886},"windows-installer-complete",[16,8932,8933],{"id":8930},"Windows Installer: Complete",[141,8935,8936,8944],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,8937,8938],{"v-slot:left":148},[20,8939,8940],{},[926,8941],{"alt":8942,"src":8943,"variant":930},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[146,8945,8946],{"v-slot:right":148},[24,8947,8948,8950,8953],{},[27,8949,2823],{},[27,8951,8952],{},"Open VirtualBox",[27,8954,8955],{},"Continue to VM creation",[11,8957,8959,8963],{"id":8958,"level":14},"install-virtualbox-macos",[16,8960,8962],{"id":8961},"install-virtualbox-on-macos","Install VirtualBox On macOS",[141,8964,8965,8984],{"gap":143,"left-width":3411,"right-width":5587,"stack":2461},[146,8966,8967],{"v-slot:left":148},[24,8968,8969,8972,8975,8978,8981],{},[27,8970,8971],{},"Install the VirtualBox host package for your Mac CPU type",[27,8973,8974],{},"Intel Mac: standard macOS host installer",[27,8976,8977],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[27,8979,8980],{},"Approve macOS security prompts if needed",[27,8982,8983],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[146,8985,8986],{"v-slot:right":148},[20,8987,8988],{},[926,8989],{"alt":8990,"src":8991,"variant":930},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,8993,8995,8999,9002],{"id":8994,"level":14},"step-1-create-vm",[16,8996,8998],{"id":8997},"step-1-create-the-vm","Step 1: Create The VM",[20,9000,9001],{},"Create a lightweight Ubuntu Server VM:",[24,9003,9004,9007,9015,9030,9042,9048,9051,9054],{},[27,9005,9006],{},"Type: Linux",[27,9008,9009,9010],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[24,9011,9012],{},[27,9013,9014],{},"Match the version to the ISO you downloaded",[27,9016,9017,9018,9021,9022],{},"Memory: ",[31,9019,9020],{},"1 GB"," course target\n",[24,9023,9024],{},[27,9025,1910,9026,9029],{},[31,9027,9028],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[27,9031,9032,9033,9035,9036],{},"Disk: ",[31,9034,8682],{}," course minimum\n",[24,9037,9038],{},[27,9039,9040,8691],{},[31,9041,8690],{},[27,9043,9044,9045,9047],{},"CPU: ",[31,9046,784],{}," core is enough for this course VM",[27,9049,9050],{},"Enable OpenSSH during install if prompted",[27,9052,9053],{},"Username: use your UCID",[27,9055,9056],{},"See the slides below for VM settings and Ubuntu install screens",[11,9058,9060,9063],{"id":9059,"level":886},"vm-setup-name-and-iso",[16,9061,9062],{"id":9059},"VM Setup: Name And ISO",[141,9064,9065,9073],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,9066,9067],{"v-slot:left":148},[20,9068,9069],{},[926,9070],{"alt":9071,"src":9072,"variant":930},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[146,9074,9075],{"v-slot:right":148},[24,9076,9077,9080,9086,9089],{},[27,9078,9079],{},"Start a new virtual machine",[27,9081,9082,9083],{},"Name it clearly, such as ",[31,9084,9085],{},"it202-vm",[27,9087,9088],{},"Choose the Ubuntu Server ISO file next",[27,9090,9091],{},"OS fields may look wrong until the ISO is selected",[11,9093,9095,9098],{"id":9094,"level":886},"vm-setup-confirm-ubuntu-iso",[16,9096,9097],{"id":9094},"VM Setup: Confirm Ubuntu ISO",[141,9099,9100,9108],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,9101,9102],{"v-slot:left":148},[20,9103,9104],{},[926,9105],{"alt":9106,"src":9107,"variant":930},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[146,9109,9110],{"v-slot:right":148},[24,9111,9112,9118,9124,9127],{},[27,9113,9114,9115],{},"Confirm OS is ",[31,9116,9117],{},"Linux",[27,9119,9120,9121],{},"Confirm distribution is ",[31,9122,9123],{},"Ubuntu",[27,9125,9126],{},"Confirm version matches your ISO",[27,9128,2479,9129,9132,9133],{},[31,9130,9131],{},"Unattended Installation"," off\n",[24,9134,9135],{},[27,9136,9137],{},"The Ubuntu installer screens are easier to teach manually",[11,9139,9141,9144],{"id":9140,"level":886},"vm-setup-memory-and-cpu",[16,9142,9143],{"id":9140},"VM Setup: Memory And CPU",[141,9145,9146,9154],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,9147,9148],{"v-slot:left":148},[20,9149,9150],{},[926,9151],{"alt":9152,"src":9153,"variant":930},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[146,9155,9156],{"v-slot:right":148},[24,9157,9158,9171,9175,9178],{},[27,9159,9017,9160,9021,9163],{},[31,9161,9162],{},"1024 MB",[24,9164,9165,9168],{},[27,9166,9167],{},"The goal is to match free-tier cloud services",[27,9169,9170],{},"Demonstrates that small apps can run with limited resources",[27,9172,9044,9173],{},[31,9174,784],{},[27,9176,9177],{},"Keep EFI off unless your machine requires it",[27,9179,9180],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,9182,9184,9187],{"id":9183,"level":886},"vm-setup-virtual-disk",[16,9185,9186],{"id":9183},"VM Setup: Virtual Disk",[141,9188,9189,9197],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,9190,9191],{"v-slot:left":148},[20,9192,9193],{},[926,9194],{"alt":9195,"src":9196,"variant":930},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[146,9198,9199],{"v-slot:right":148},[24,9200,9201,9207,9210,9222],{},[27,9202,9203,9204],{},"Disk type: ",[31,9205,9206],{},"VDI",[27,9208,9209],{},"Storage: dynamically allocated",[27,9211,9212,9213,9215],{},"Minimum: ",[31,9214,8682],{},[24,9216,9217],{},[27,9218,9219,9221],{},[31,9220,8690],{}," is safer if you have room",[27,9223,9224],{},"Dynamic disk uses space as needed, not all at once",[11,9226,9228,9231],{"id":9227,"level":886},"vm-setup-start-with-gui",[16,9229,9230],{"id":9227},"VM Setup: Start With GUI",[141,9232,9233,9241],{"gap":143,"left-width":2459,"right-width":2460,"stack":2461},[146,9234,9235],{"v-slot:left":148},[20,9236,9237],{},[926,9238],{"alt":9239,"src":9240,"variant":930},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[146,9242,9243],{"v-slot:right":148},[24,9244,9245,9248,9258,9261],{},[27,9246,9247],{},"Select the newly created VM",[27,9249,951,9250,9253],{},[31,9251,9252],{},"Start",[24,9254,9255],{},[27,9256,9257],{},"Choose the normal GUI start for the first boot",[27,9259,9260],{},"Complete the Ubuntu installer in the VM window",[27,9262,9263,9264],{},"After install and SSH setup, future starts can be headless\n",[24,9265,9266],{},[27,9267,9268,9269,9271],{},"You will connect with ",[31,9270,4337],{}," when you need the VM",[11,9273,9275,9279,9282],{"id":9274,"level":14},"ubuntu-installer",[16,9276,9278],{"id":9277},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[20,9280,9281],{},"Use the Ubuntu Server installer after the VM starts:",[24,9283,9284,9287,9290,9293,9296,9299,9332],{},[27,9285,9286],{},"Choose the default course options unless noted",[27,9288,9289],{},"Continue without updating the installer if instructed",[27,9291,9292],{},"Use your UCID for the Ubuntu username",[27,9294,9295],{},"Install OpenSSH server during setup",[27,9297,9298],{},"Skip optional server snaps",[27,9300,9301,9302],{},"Keyboard navigation:\n",[24,9303,9304,9311,9321,9327],{},[27,9305,9306,9310],{},[9307,9308,9309],"kbd",{},"Tab"," moves between fields and buttons",[27,9312,9313,9316,9317,9320],{},[9307,9314,9315],{},"Up"," \u002F ",[9307,9318,9319],{},"Down"," moves through lists",[27,9322,9323,9326],{},[9307,9324,9325],{},"Space"," toggles checkboxes",[27,9328,9329,9331],{},[9307,9330,1994],{}," confirms the selected option",[27,9333,9334],{},"See the slides below for the installer screens",[11,9336,9338,9342],{"id":9337,"level":886},"ubuntu-installer-boot-menu",[16,9339,9341],{"id":9340},"step-21-boot-menu","Step 2.1: Boot Menu",[141,9343,9346,9355],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},"1.75fr","0.65fr",[146,9347,9348],{"v-slot:left":148},[20,9349,9350],{},[926,9351],{"alt":9352,"src":9353,"variant":9354},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[146,9356,9357],{"v-slot:right":148},[24,9358,9359,9364,9368],{},[27,9360,3426,9361],{},[31,9362,9363],{},"Try or Install Ubuntu Server",[27,9365,2026,9366],{},[9307,9367,1994],{},[27,9369,9370],{},"This starts the Ubuntu Server installer",[11,9372,9374,9378],{"id":9373,"level":886},"ubuntu-installer-language",[16,9375,9377],{"id":9376},"step-22-language","Step 2.2: Language",[141,9379,9380,9388],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9381,9382],{"v-slot:left":148},[20,9383,9384],{},[926,9385],{"alt":9386,"src":9387,"variant":9354},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[146,9389,9390],{"v-slot:right":148},[24,9391,9392,9395,9401],{},[27,9393,9394],{},"Choose your preferred language",[27,9396,9397,9400],{},[31,9398,9399],{},"English"," is the expected course screenshot path",[27,9402,2026,9403,9405],{},[9307,9404,1994],{}," to continue",[11,9407,9409,9413],{"id":9408,"level":886},"ubuntu-installer-update",[16,9410,9412],{"id":9411},"step-23-update-prompt","Step 2.3: Update Prompt",[141,9414,9415,9423],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9416,9417],{"v-slot:left":148},[20,9418,9419],{},[926,9420],{"alt":9421,"src":9422,"variant":9354},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[146,9424,9425],{"v-slot:right":148},[24,9426,9427,9437,9440],{},[27,9428,3426,9429,9432],{},[31,9430,9431],{},"Continue without updating",[24,9433,9434],{},[27,9435,9436],{},"If I forget to update the image, it's the second option",[27,9438,9439],{},"Keeps the install path consistent",[27,9441,9442],{},"Package updates happen after Ubuntu is installed",[11,9444,9446,9450],{"id":9445,"level":886},"ubuntu-installer-keyboard",[16,9447,9449],{"id":9448},"step-24-keyboard","Step 2.4: Keyboard",[141,9451,9452,9460],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9453,9454],{"v-slot:left":148},[20,9455,9456],{},[926,9457],{"alt":9458,"src":9459,"variant":9354},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[146,9461,9462],{"v-slot:right":148},[24,9463,9464,9467,9473],{},[27,9465,9466],{},"Keep the detected keyboard layout if it matches",[27,9468,9469,9470],{},"Common setting: ",[31,9471,9472],{},"English (US)",[27,9474,9475],{},"Use Identify keyboard only if typing is wrong",[11,9477,9479,9483],{"id":9478,"level":886},"ubuntu-installer-install-type",[16,9480,9482],{"id":9481},"step-25-install-type","Step 2.5: Install Type",[141,9484,9485,9493],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9486,9487],{"v-slot:left":148},[20,9488,9489],{},[926,9490],{"alt":9491,"src":9492,"variant":9354},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[146,9494,9495],{"v-slot:right":148},[24,9496,9497,9507,9510],{},[27,9498,9499,9500,9503,9504],{},"Select ",[31,9501,9502],{},"Ubuntu Server (minimized)","; don't choose full ",[31,9505,9506],{},"Ubuntu Server",[27,9508,9509],{},"Keep third-party drivers unchecked",[27,9511,9512],{},"Minimized keeps the VM lighter and aids future lessons",[11,9514,9516,9520],{"id":9515,"level":886},"ubuntu-installer-network",[16,9517,9519],{"id":9518},"step-26-network","Step 2.6: Network",[141,9521,9522,9530],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9523,9524],{"v-slot:left":148},[20,9525,9526],{},[926,9527],{"alt":9528,"src":9529,"variant":9354},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[146,9531,9532],{"v-slot:right":148},[24,9533,9534,9537,9543],{},[27,9535,9536],{},"DHCP address is expected",[27,9538,9539,9542],{},[31,9540,9541],{},"10.0.2.15"," is normal for VirtualBox NAT",[27,9544,9545],{},"Leave the network settings alone",[11,9547,9549,9553],{"id":9548,"level":886},"ubuntu-installer-proxy",[16,9550,9552],{"id":9551},"step-27-proxy","Step 2.7: Proxy",[141,9554,9555,9563],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9556,9557],{"v-slot:left":148},[20,9558,9559],{},[926,9560],{"alt":9561,"src":9562,"variant":9354},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[146,9564,9565],{"v-slot:right":148},[24,9566,9567,9570,9573],{},[27,9568,9569],{},"Leave proxy blank",[27,9571,9572],{},"Only fill this in if your network requires a proxy",[27,9574,9575],{},"Most student home networks do not need one",[11,9577,9579,9583],{"id":9578,"level":886},"ubuntu-installer-mirror",[16,9580,9582],{"id":9581},"step-28-mirror","Step 2.8: Mirror",[141,9584,9585,9593],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9586,9587],{"v-slot:left":148},[20,9588,9589],{},[926,9590],{"alt":9591,"src":9592,"variant":9354},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[146,9594,9595],{"v-slot:right":148},[24,9596,9597,9600,9603],{},[27,9598,9599],{},"Keep the default Ubuntu archive mirror",[27,9601,9602],{},"Wait for the mirror check to finish",[27,9604,9605],{},"Continue when the installer allows it",[11,9607,9609,9613],{"id":9608,"level":886},"ubuntu-installer-storage-guided",[16,9610,9612],{"id":9611},"step-29-guided-storage","Step 2.9: Guided Storage",[141,9614,9615,9623],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9616,9617],{"v-slot:left":148},[20,9618,9619],{},[926,9620],{"alt":9621,"src":9622,"variant":9354},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[146,9624,9625],{"v-slot:right":148},[24,9626,9627,9630,9633],{},[27,9628,9629],{},"Use the entire virtual disk",[27,9631,9632],{},"LVM is optional, not needed for this course VM",[27,9634,9635],{},"Leave encryption off",[11,9637,9639,9643],{"id":9638,"level":886},"ubuntu-installer-storage-summary",[16,9640,9642],{"id":9641},"step-210-storage-summary","Step 2.10: Storage Summary",[141,9644,9645,9653],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9646,9647],{"v-slot:left":148},[20,9648,9649],{},[926,9650],{"alt":9651,"src":9652,"variant":9354},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[146,9654,9655],{"v-slot:right":148},[24,9656,9657,9660,9663],{},[27,9658,9659],{},"Confirm the virtual disk is selected",[27,9661,9662],{},"This only affects the VM disk file",[27,9664,9665],{},"Continue when the layout looks correct",[11,9667,9669,9673],{"id":9668,"level":886},"ubuntu-installer-confirm-storage",[16,9670,9672],{"id":9671},"step-211-confirm-storage","Step 2.11: Confirm Storage",[141,9674,9675,9683],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9676,9677],{"v-slot:left":148},[20,9678,9679],{},[926,9680],{"alt":9681,"src":9682,"variant":9354},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[146,9684,9685],{"v-slot:right":148},[24,9686,9687,9690,9693],{},[27,9688,9689],{},"Confirm the virtual disk format",[27,9691,9692],{},"This does not erase your host computer files",[27,9694,9695],{},"It formats the VM's virtual disk",[11,9697,9699,9703],{"id":9698,"level":886},"ubuntu-installer-profile",[16,9700,9702],{"id":9701},"step-212-profile","Step 2.12: Profile",[141,9704,9705,9713],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9706,9707],{"v-slot:left":148},[20,9708,9709],{},[926,9710],{"alt":9711,"src":9712,"variant":9354},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[146,9714,9715],{"v-slot:right":148},[24,9716,9717,9720,9725,9727],{},[27,9718,9719],{},"Your name: your UCID or name is fine",[27,9721,9722,9723],{},"Server name: ",[31,9724,9085],{},[27,9726,5541],{},[27,9728,9729],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9731,9733,9737],{"id":9732,"level":886},"ubuntu-installer-pro",[16,9734,9736],{"id":9735},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[141,9738,9739,9747],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9740,9741],{"v-slot:left":148},[20,9742,9743],{},[926,9744],{"alt":9745,"src":9746,"variant":9354},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[146,9748,9749],{"v-slot:right":148},[24,9750,9751,9756,9759],{},[27,9752,3426,9753],{},[31,9754,9755],{},"Skip for now",[27,9757,9758],{},"Ubuntu Pro is not needed for the course VM",[27,9760,9761],{},"You can continue without an Ubuntu account",[11,9763,9765,9769],{"id":9764,"level":886},"ubuntu-installer-ssh",[16,9766,9768],{"id":9767},"step-214-ssh","Step 2.14: SSH",[141,9770,9771,9779],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9772,9773],{"v-slot:left":148},[20,9774,9775],{},[926,9776],{"alt":9777,"src":9778,"variant":9354},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[146,9780,9781],{"v-slot:right":148},[24,9782,9783,9788,9791],{},[27,9784,521,9785],{},[31,9786,9787],{},"Install OpenSSH server",[27,9789,9790],{},"Password authentication is fine for this local VM",[27,9792,9793],{},"No need to import SSH keys for this course setup",[11,9795,9797,9801],{"id":9796,"level":886},"ubuntu-installer-snaps",[16,9798,9800],{"id":9799},"step-215-featured-snaps","Step 2.15: Featured Snaps",[141,9802,9803,9811],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9804,9805],{"v-slot:left":148},[20,9806,9807],{},[926,9808],{"alt":9809,"src":9810,"variant":9354},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[146,9812,9813],{"v-slot:right":148},[24,9814,9815,9818,9823],{},[27,9816,9817],{},"Leave all featured snaps unchecked",[27,9819,9820,9821],{},"Apache, PHP, and MySQL are installed later with ",[31,9822,6817],{},[27,9824,9825],{},"Continue without selecting extra packages",[11,9827,9829,9833],{"id":9828,"level":886},"ubuntu-installer-installing",[16,9830,9832],{"id":9831},"step-216-installing","Step 2.16: Installing",[141,9834,9835,9843],{"gap":782,"left-width":9344,"right-width":9345,"stack":2461},[146,9836,9837],{"v-slot:left":148},[20,9838,9839],{},[926,9840],{"alt":9841,"src":9842,"variant":9354},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[146,9844,9845,9870],{"v-slot:right":148},[24,9846,9847,9850,9853,9861,9867],{},[27,9848,9849],{},"Installation can take a while",[27,9851,9852],{},"High CPU during install is normal",[27,9854,9855,9856,9858,9859],{},"If install struggles at ",[31,9857,9020],{},", recreate the VM with ",[31,9860,9028],{},[27,9862,9863,9864,9866],{},"Keep the course target at ",[31,9865,9020],{}," after setup if possible",[27,9868,9869],{},"Reboot once complete",[2675,9871,9872],{"type":3947},[20,9873,9874],{},"These target resources stay close to common cloud free-tier VMs",[20,9876,2683],{},[11,9878,9880,9884,9887],{"id":9879,"level":14},"step-2-networking",[16,9881,9883],{"id":9882},"virtualbox-configure-networking","VirtualBox: Configure Networking",[20,9885,9886],{},"Use one NAT adapter with port forwarding:",[24,9888,9889,9895,9904,9912,9917],{},[27,9890,9891,9892],{},"VM internet: ",[31,9893,9894],{},"NAT",[27,9896,9897,9898,9901,9902],{},"Host SSH: host ",[31,9899,9900],{},"22"," -> guest ",[31,9903,9900],{},[27,9905,9906,9907,9901,9910],{},"Host browser: host ",[31,9908,9909],{},"3000",[31,9911,8499],{},[27,9913,1910,9914,9916],{},[31,9915,8717],{}," from the host computer",[27,9918,9919],{},"See the slides below for adapter and port-forwarding screens",[11,9921,9923,9927,9940],{"id":9922,"level":886},"adapter-settings-screen",[16,9924,9926],{"id":9925},"adapter-settings","Adapter Settings",[24,9928,9929,9932,9937],{},[27,9930,9931],{},"Adapter 1 enabled",[27,9933,9934,9935],{},"Attached to ",[31,9936,9894],{},[27,9938,9939],{},"No second adapter needed for the baseline path",[20,9941,9942],{},[926,9943],{"alt":9944,"src":9945,"variant":9354},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,9947,9949,9953,9981],{"id":9948,"level":886},"port-forwarding-screen",[16,9950,9952],{"id":9951},"port-forwarding","Port Forwarding",[24,9954,9955,9963,9970],{},[27,9956,9957,9958,9960,9961],{},"SSH: host ",[31,9959,9900],{}," to guest ",[31,9962,9900],{},[27,9964,9965,9966,9960,9968],{},"Apache HTTP: host ",[31,9967,9909],{},[31,9969,8499],{},[27,9971,9972,9973,9975,9976,9960,9979],{},"If host ",[31,9974,9900],{}," is already busy, use host ",[31,9977,9978],{},"2222",[31,9980,9900],{},[20,9982,9983],{},[926,9984],{"alt":9985,"src":9986,"variant":9354},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,9988,9990,9994,9997,10000,10003,10006],{"id":9989,"level":14},"step-3-connect-ssh",[16,9991,9993],{"id":9992},"step-3-connect-with-ssh","Step 3: Connect With SSH",[20,9995,9996],{},"Run from your host terminal:",[115,9998],{"language":118,"src":9999},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[20,10001,10002],{},"First connection prompt:",[115,10004],{"language":164,"src":10005},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[24,10007,10008,10015,10024,10027,10030],{},[27,10009,10010,10011,10014],{},"Replace ",[31,10012,10013],{},"your_ucid"," with your UCID",[27,10016,10017,10018,10020,10021,10023],{},"Type ",[31,10019,3874],{}," once for this course VM on ",[31,10022,8717],{}," (if prompted like the example above)",[27,10025,10026],{},"Enter your Ubuntu password",[27,10028,10029],{},"After login, commands run inside Ubuntu",[27,10031,10032,1961,10035,10038],{},[31,10033,10034],{},"exit",[31,10036,10037],{},"logout"," disconnects from the VM",[11,10040,10042,10046,10049],{"id":10041,"level":14},"step-4-confirm-network",[16,10043,10045],{"id":10044},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[20,10047,10048],{},"Run inside Ubuntu through SSH:",[141,10050,10051,10093],{"gap":143,"left-width":3003,"right-width":144,"stack":2461},[146,10052,10053,10056,10059],{"v-slot:left":148},[20,10054,10055],{},"Network check:",[115,10057],{"language":118,"src":10058},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[24,10060,10061,10067,10073,10079,10085],{},[27,10062,10063,10066],{},[31,10064,10065],{},"ping",": confirms basic network access",[27,10068,10069,10072],{},[31,10070,10071],{},"-c 4",": stop after four replies",[27,10074,10075,10078],{},[31,10076,10077],{},"apt update",": refreshes package indexes",[27,10080,10081,10084],{},[31,10082,10083],{},"apt upgrade",": applies available package updates",[27,10086,2920,10087,10089,10090],{},[31,10088,10065],{}," is not found, run ",[31,10091,10092],{},"sudo apt install iputils-ping",[146,10094,10095,10098,10101],{"v-slot:right":148},[20,10096,10097],{},"Port-forwarding check:",[115,10099],{"language":118,"src":10100},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[24,10102,10103,10108,10111,10115],{},[27,10104,10105,10106],{},"The VM may show ",[31,10107,9541],{},[27,10109,10110],{},"That is normal for VirtualBox NAT",[27,10112,1910,10113,9916],{},[31,10114,8717],{},[27,10116,10117],{},"Port forwarding routes host traffic into the VM",[11,10119,10121,10125],{"id":10120,"level":14},"step-5-shared-folder",[16,10122,10124],{"id":10123},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[141,10126,10127,10161],{"gap":143,"left-width":2460,"right-width":3003,"stack":2461},[146,10128,10129,10132],{"v-slot:left":148},[20,10130,10131],{},"In VirtualBox:",[24,10133,10134,10137,10140,10143,10146,10149,10152,10155,10158],{},[27,10135,10136],{},"Open VM settings",[27,10138,10139],{},"Choose Shared Folders",[27,10141,10142],{},"Folder Path: your cloned course repository folder",[27,10144,10145],{},"Folder Name: a simple repo name with no spaces",[27,10147,10148],{},"Mount Point: leave blank",[27,10150,10151],{},"Read-only: off",[27,10153,10154],{},"Auto-mount: on",[27,10156,10157],{},"Make Machine-permanent: on",[27,10159,10160],{},"Make Global: off",[146,10162,10163],{"v-slot:right":148},[20,10164,10165],{},[926,10166],{"alt":10167,"src":10168,"variant":930},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,10170,10172,10176,10179,10182],{"id":10171,"level":14},"step-6-guest-additions",[16,10173,10175],{"id":10174},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[20,10177,10178],{},"Run inside Ubuntu:",[115,10180],{"language":118,"src":10181},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[24,10183,10184,10191,10197],{},[27,10185,3109,10186,34,10188,10190],{},[31,10187,10077],{},[31,10189,10083],{}," first only if you skipped the Step 4 updates",[27,10192,10193,10196],{},[31,10194,10195],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[27,10198,10199],{},"Reboot after the group step on the next slide",[11,10201,10203,10207,10210,10213],{"id":10202,"level":886},"step-6b-confirm-vboxsf",[16,10204,10206],{"id":10205},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[20,10208,10209],{},"Reconnect with SSH, then run inside Ubuntu:",[115,10211],{"language":118,"src":10212},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-1-check-the-share-06.sh",[24,10214,10215,10221,10227],{},[27,10216,10217,10220],{},[31,10218,10219],{},"ls \u002Fmedia",": shows available mounted folders",[27,10222,10223,10226],{},[31,10224,10225],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[27,10228,10229],{},"Permission denied is common the first time",[11,10231,10233,10237,10240,10243],{"id":10232,"level":14},"step-7-locate-share",[16,10234,10236],{"id":10235},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[20,10238,10239],{},"If the shared folder exists but says permission denied:",[115,10241],{"language":118,"src":10242},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[24,10244,10245,10251,10257],{},[27,10246,10247,10250],{},[31,10248,10249],{},"vboxsf",": group allowed to read VirtualBox shared folders",[27,10252,10253,10256],{},[31,10254,10255],{},"$USER",": your Ubuntu login user for terminal access",[27,10258,10259],{},"Reboot applies the shared-folder support and new group membership",[11,10261,10263,10267,10269,10272,10289,10292],{"id":10262,"level":886},"step-7b-locate-share",[16,10264,10266],{"id":10265},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[20,10268,10209],{},[115,10270],{"language":118,"src":10271},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-1-locate-the-shar-08.sh",[24,10273,10274,10280,10286],{},[27,10275,10276,10279],{},[31,10277,10278],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[27,10281,10282,10285],{},[31,10283,10284],{},"\u003Cshared-folder>",": your shared course repo folder name",[27,10287,10288],{},"Use the folder that points to your repository",[20,10290,10291],{},"Expected repo folders:",[24,10293,10294,10298,10302,10306],{},[27,10295,10296],{},[31,10297,1587],{},[27,10299,10300],{},[31,10301,6262],{},[27,10303,10304],{},[31,10305,6265],{},[27,10307,10308],{},[31,10309,6268],{},[11,10311,10313,10317,10332],{"id":10312,"level":886},"step-7-2-shared-folder-check",[16,10314,10316],{"id":10315},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[24,10318,10319,10322,10329],{},[27,10320,10321],{},"Edit a small file from VS Code on host",[27,10323,3109,10324,1961,10326,10328],{},[31,10325,1576],{},[31,10327,1793],{}," inside Ubuntu",[27,10330,10331],{},"Confirm Ubuntu sees the same file content",[20,10333,10334],{},"If the file does not match, stop and fix the share before Apache setup",[11,10336,10338,10342,10344,10347],{"id":10337,"level":14},"step-8-install-apache-php-mysql",[16,10339,10341],{"id":10340},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[20,10343,10178],{},[115,10345],{"language":118,"src":10346},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[24,10348,10349,10355,10360,10366,10372,10378],{},[27,10350,10351,10354],{},[31,10352,10353],{},"apache2",": web server",[27,10356,10357,10359],{},[31,10358,6055],{},": PHP runtime",[27,10361,10362,10365],{},[31,10363,10364],{},"libapache2-mod-php",": lets Apache execute PHP files",[27,10367,10368,10371],{},[31,10369,10370],{},"mysql-server",": local MySQL database server",[27,10373,10374,10377],{},[31,10375,10376],{},"php-mysql",": lets PHP connect to MySQL",[27,10379,3109,10380,34,10382,10384],{},[31,10381,10077],{},[31,10383,10083],{}," first only if they have not been run recently",[11,10386,10388,10392,10399],{"id":10387,"level":886},"optional-swap-check",[16,10389,10391],{"id":10390},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[20,10393,10394,10395,10398],{},"Ubuntu usually has swap already. Only add this if ",[31,10396,10397],{},"swapon --show"," prints nothing.",[141,10400,10401,10415],{"gap":143,"left-width":144,"right-width":144},[146,10402,10403,10406,10409,10412],{"v-slot:left":148},[20,10404,10405],{},"Check first:",[115,10407],{"language":118,"src":10408},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[20,10410,10411],{},"Add a small swap file only if swap is off:",[115,10413],{"language":118,"src":10414},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[146,10416,10417],{"v-slot:right":148},[24,10418,10419,10422,10427,10430],{},[27,10420,10421],{},"Swap gives Ubuntu emergency disk-backed memory",[27,10423,10424,10425],{},"It helps when installs or MySQL briefly need more than ",[31,10426,9020],{},[27,10428,10429],{},"It is slower than RAM, so it is not a performance upgrade",[27,10431,10432],{},"Do not run the setup again if swap already exists",[11,10434,10436,10440,10446],{"id":10435,"level":886},"optional-apache-low-memory",[16,10437,10439],{"id":10438},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[20,10441,10442,10443,10445],{},"Use this if the ",[31,10444,9020],{}," VM feels unstable or Apache starts too many PHP workers.",[141,10447,10448,10461],{"gap":143,"left-width":144,"right-width":144},[146,10449,10450,10453,10458],{"v-slot:left":148},[20,10451,10452],{},"Edit Apache prefork settings in:",[20,10454,10455],{},[31,10456,10457],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[115,10459],{"language":118,"src":10460},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[146,10462,10463,10466,10470],{"v-slot:right":148},[20,10464,10465],{},"Change the existing values to:",[115,10467],{"language":10468,"src":10469},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[24,10471,10472,10478,10481,10488],{},[27,10473,10474,10475],{},"Edit the existing lines inside ",[31,10476,10477],{},"\u003CIfModule mpm_prefork_module>",[27,10479,10480],{},"If a line is missing, add it inside that same block",[27,10482,10483,10484,10487],{},"Do not paste a second ",[31,10485,10486],{},"\u003CIfModule>"," block",[27,10489,10490],{},"Restart Apache after config changes",[11,10492,10494,10498,10504],{"id":10493,"level":886},"optional-mysql-low-memory",[16,10495,10497],{"id":10496},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[20,10499,10500,10501,10503],{},"Use this only if MySQL struggles on the ",[31,10502,9020],{}," VM.",[141,10505,10506,10519],{"gap":143,"left-width":144,"right-width":144},[146,10507,10508,10511,10516],{"v-slot:left":148},[20,10509,10510],{},"Edit MySQL server settings in:",[20,10512,10513],{},[31,10514,10515],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[115,10517],{"language":118,"src":10518},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[146,10520,10521,10527,10530],{"v-slot:right":148},[20,10522,10523,10524,2018],{},"Add or edit these under ",[31,10525,10526],{},"[mysqld]",[115,10528],{"language":6858,"src":10529},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[24,10531,10532,10538,10543,10546],{},[27,10533,10534,10535,10537],{},"Keep these under the existing ",[31,10536,10526],{}," heading",[27,10539,10540,10541,10537],{},"Do not create a second ",[31,10542,10526],{},[27,10544,10545],{},"If either setting already exists, edit it instead of adding a duplicate",[27,10547,10548],{},"Restart MySQL after config changes",[11,10550,10552,10555,10558,10561],{"id":10551,"level":886},"low-memory-diagnostics",[16,10553,10554],{"id":10551},"Low Memory Diagnostics",[20,10556,10557],{},"Run these after the minor tuning checks:",[115,10559],{"language":118,"src":10560},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[24,10562,10563,10569,10574,10580,10587],{},[27,10564,10565,10568],{},[31,10566,10567],{},"free -h",": shows RAM and swap",[27,10570,10571,10573],{},[31,10572,10397],{},": confirms whether swap is active",[27,10575,10576,10579],{},[31,10577,10578],{},"systemctl status",": checks whether Apache and MySQL are running",[27,10581,10582,10583,10586],{},"No output from the ",[31,10584,10585],{},"grep"," line is usually good",[27,10588,10589],{},"Do not tune randomly; change one setting, restart, then retest",[11,10591,10593,10597,10599,10602,10605,10608],{"id":10592,"level":14},"step-9-create-local-mysql-db",[16,10594,10596],{"id":10595},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[20,10598,10178],{},[115,10600],{"language":118,"src":10601},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-11.sh",[20,10603,10604],{},"Then run in the MySQL prompt:",[115,10606],{"language":6268,"src":10607},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-12.sql",[24,10609,10610,10614,10617],{},[27,10611,10010,10612,10014],{},[31,10613,10013],{},[27,10615,10616],{},"Database name and username should match your UCID",[27,10618,10619],{},"Password is local-only unless your instructor says otherwise",[11,10621,10623,10626,10629,10642,10645,10651],{"id":10622,"level":14},"local-vs-remote-database",[16,10624,10625],{"id":10622},"Local Vs Remote Database",[20,10627,10628],{},"This MySQL database is only for local testing:",[24,10630,10631,10635,10637,10639],{},[27,10632,5529,10633],{},[31,10634,8717],{},[27,10636,5544],{},[27,10638,5541],{},[27,10640,10641],{},"Password: your local password",[20,10643,10644],{},"Render uses the instructor-provided remote database connection string",[20,10646,10647,10648],{},"Get that string from ",[694,10649,5555],{"href":5555,"rel":10650},[698],[20,10652,10653],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10655,10657,10661,10663,10666,10668,10671,10674],{"id":10656,"level":14},"step-10-confirm-local-mysql",[16,10658,10660],{"id":10659},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[20,10662,10178],{},[115,10664],{"language":118,"src":10665},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[20,10667,5048],{},[115,10669],{"language":6268,"src":10670},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[20,10672,10673],{},"Expected:",[24,10675,10676,10682],{},[27,10677,10678,10681],{},[31,10679,10680],{},"SELECT DATABASE()"," returns your UCID",[27,10683,10684,10687],{},[31,10685,10686],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10689,10691,10697,10700,10703,10706],{"id":10690,"level":14},"step-11-documentroot",[16,10692,10694,10695],{"id":10693},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[31,10696,1587],{},[20,10698,10699],{},"Apache should serve:",[115,10701],{"language":164,"src":10702},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[20,10704,10705],{},"Do not serve the whole repo",[24,10707,10708,10717],{},[27,10709,10710,731,10712,734,10714,10716],{},[31,10711,6262],{},[31,10713,6265],{},[31,10715,6268],{}," stay outside the web root",[27,10718,10719,10721],{},[31,10720,1587],{}," is the browser-facing folder",[11,10723,10725,10729,10732,10737,10739,10744,10747,10750],{"id":10724,"level":886},"apache-site-config",[16,10726,10728],{"id":10727},"step-111-apache-site-config","Step 11.1: Apache Site Config",[20,10730,10731],{},"Create or edit this Apache site config file inside Ubuntu:",[20,10733,10734],{},[31,10735,10736],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10738,151],{},[20,10740,10741],{},[31,10742,10743],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10745,10746],{},"Add this content to that file:",[115,10748],{"language":10468,"src":10749},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-1-apache-site-co-16.txt",[24,10751,10752,10757,10763,10768],{},[27,10753,10010,10754,10756],{},[31,10755,10284],{}," with the actual shared folder name",[27,10758,10759,10760],{},"Save the file as ",[31,10761,10762],{},"it202.conf",[27,10764,10765,10766],{},"Apache listens on guest port ",[31,10767,8499],{},[27,10769,10770,10771],{},"Host browser reaches it through ",[31,10772,8575],{},[11,10774,10776,10780,10782,10785],{"id":10775,"level":886},"enable-site",[16,10777,10779],{"id":10778},"step-112-enable-the-site","Step 11.2: Enable The Site",[20,10781,10178],{},[115,10783],{"language":118,"src":10784},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-2-enable-the-sit-17.sh",[24,10786,10787,10793,10799,10805,10813,10819],{},[27,10788,10789,10792],{},[31,10790,10791],{},"a2ensite",": enable a site config",[27,10794,10795,10798],{},[31,10796,10797],{},"a2dissite",": disable a site config",[27,10800,10801,10804],{},[31,10802,10803],{},"www-data",": Apache's user for browser requests",[27,10806,10807,10808,7010,10810,10812],{},"Adding ",[31,10809,10803],{},[31,10811,10249],{}," lets Apache read the shared folder",[27,10814,10815,10818],{},[31,10816,10817],{},"configtest",": check syntax before reload",[27,10820,10821,10824],{},[31,10822,10823],{},"restart",": applies the Apache user group change",[11,10826,10828,10832,10835,10838,10841],{"id":10827,"level":14},"step-12-php-check-page",[16,10829,10831],{"id":10830},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[20,10833,10834],{},"Create this file on the host:",[115,10836],{"language":164,"src":10837},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-18.txt",[20,10839,10840],{},"Example content:",[115,10842],{"language":6055,"src":10843},"\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,10845,10847,10850,10853,10856,10858],{"id":10846,"level":14},"final-browser-check",[16,10848,10849],{"id":10846},"Final Browser Check",[20,10851,10852],{},"Open from host browser:",[115,10854],{"language":164,"src":10855},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[20,10857,10673],{},[24,10859,10860,10863,10866,10869],{},[27,10861,10862],{},"Message appears",[27,10864,10865],{},"Time appears",[27,10867,10868],{},"PHP code is not shown as raw text",[27,10870,10871],{},"Editing the file on host changes output after refresh",[11,10873,10875,10878],{"id":10874,"level":14},"common-problems",[16,10876,10877],{"id":10874},"Common Problems",[24,10879,10880,10883,10886,10891,10894,10907,10917],{},[27,10881,10882],{},"Browser timeout: missing or wrong port-forwarding rule",[27,10884,10885],{},"Connection refused: Apache not running",[27,10887,10888,10889],{},"No internet in VM: check Adapter 1 is still ",[31,10890,9894],{},[27,10892,10893],{},"Shared folder missing: check Auto-mount and guest utilities",[27,10895,10896,10897,10900,10901,10903,10904,10906],{},"Browser shows ",[31,10898,10899],{},"403 Forbidden",": confirm ",[31,10902,10803],{}," is in ",[31,10905,10249],{},", then restart Apache or reboot",[27,10908,10909,10910,10913,10914,10916],{},"Permission denied on ",[31,10911,10912],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[31,10915,10249],{}," and reboot",[27,10918,10919],{},"Raw PHP code: PHP module not running through Apache",[11,10921,10923,10926,10929],{"id":10922,"level":14},"recovery-routine",[16,10924,10925],{"id":10922},"Recovery Routine",[20,10927,10928],{},"Check in this order:",[487,10930,10931,10934,10940,10946,10951,10959,10966,10972,10977,10986],{},[27,10932,10933],{},"VM is running",[27,10935,10936,10939],{},[31,10937,10938],{},"ping github.com"," works inside Ubuntu",[27,10941,10942,10945],{},[31,10943,10944],{},"ssh username@localhost"," works from host",[27,10947,10948,10950],{},[31,10949,10225],{}," shows the shared repo",[27,10952,10953,10956,10957],{},[31,10954,10955],{},"groups"," includes ",[31,10958,10249],{},[27,10960,10961,10956,10964],{},[31,10962,10963],{},"id www-data",[31,10965,10249],{},[27,10967,10968,10971],{},[31,10969,10970],{},"sudo systemctl status apache2"," is active",[27,10973,10974,10971],{},[31,10975,10976],{},"sudo systemctl status mysql",[27,10978,10979,10982,10983],{},[31,10980,10981],{},"sudo apache2ctl configtest"," says ",[31,10984,10985],{},"Syntax OK",[27,10987,10988,10991],{},[31,10989,10990],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,10993,10994,10996],{"id":651,"level":14},[16,10995,652],{"id":651},[141,10997,10998,11039],{"gap":143,"left-width":144,"right-width":144},[146,10999,11000,11002,11008,11017,11022,11028,11034],{"v-slot:left":148},[658,11001,661],{"id":660},[20,11003,11004,11007],{},[908,11005,11006],{},"VM"," - separate computer running inside your host computer",[20,11009,11010,11013,11014,11016],{},[908,11011,11012],{},"Port forwarding"," - host ",[31,11015,8717],{}," traffic routed into the VM",[20,11018,11019,11021],{},[908,11020,10249],{}," - VirtualBox shared-folder permission group",[20,11023,11024,11027],{},[908,11025,11026],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[20,11029,11030,11033],{},[908,11031,11032],{},"DocumentRoot"," - folder Apache serves to browsers",[20,11035,11036,11038],{},[908,11037,9894],{}," - VM network mode that gives the VM outbound internet access",[146,11040,11041,11043],{"v-slot:right":148},[658,11042,687],{"id":648},[24,11044,11045,11051,11058,11065,11072,11079,11085],{},[27,11046,11047],{},[694,11048,11050],{"href":8641,"rel":11049},[698],"VirtualBox Downloads",[27,11052,11053],{},[694,11054,11057],{"href":11055,"rel":11056},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[698],"VirtualBox Manual: Host And Guest Combinations",[27,11059,11060],{},[694,11061,11064],{"href":11062,"rel":11063},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[698],"VirtualBox Manual: Installation",[27,11066,11067],{},[694,11068,11071],{"href":11069,"rel":11070},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[698],"VirtualBox Manual: Shared Folders",[27,11073,11074],{},[694,11075,11078],{"href":11076,"rel":11077},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[698],"VirtualBox Manual: NAT Port Forwarding",[27,11080,11081],{},[694,11082,11084],{"href":8659,"rel":11083},[698],"Ubuntu Server: Installer",[27,11086,11087],{},[694,11088,11091],{"href":11089,"rel":11090},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[698],"Ubuntu Server: OpenSSH Server",[11,11093,11094,11096,11098],{"id":717,"level":14},[16,11095,720],{"id":717},[20,11097,723],{},[24,11099,11100,11103,11106,11109,11112,11117],{},[27,11101,11102],{},"Pick the correct Ubuntu ISO for your host CPU",[27,11104,11105],{},"Configure NAT port forwarding",[27,11107,11108],{},"Connect to Ubuntu with SSH",[27,11110,11111],{},"Find the VirtualBox shared repo",[27,11113,11114,11115],{},"Configure Apache to serve ",[31,11116,1587],{},[27,11118,11119],{},"Create a local MySQL database and user named after your UCID",{"title":148,"searchDepth":754,"depth":754,"links":11121},[11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11180,11181,11182,11183,11184,11185,11186,11187],{"id":8521,"depth":754,"text":8513},{"id":8547,"depth":754,"text":8550},{"id":8592,"depth":754,"text":8595},{"id":107,"depth":754,"text":110},{"id":8697,"depth":754,"text":8700},{"id":8732,"depth":754,"text":8733},{"id":8756,"depth":754,"text":8759},{"id":8788,"depth":754,"text":8791},{"id":8814,"depth":754,"text":8817},{"id":8843,"depth":754,"text":8846},{"id":8875,"depth":754,"text":8876},{"id":8899,"depth":754,"text":8902},{"id":8930,"depth":754,"text":8933},{"id":8961,"depth":754,"text":8962},{"id":8997,"depth":754,"text":8998},{"id":9059,"depth":754,"text":9062},{"id":9094,"depth":754,"text":9097},{"id":9140,"depth":754,"text":9143},{"id":9183,"depth":754,"text":9186},{"id":9227,"depth":754,"text":9230},{"id":9277,"depth":754,"text":9278},{"id":9340,"depth":754,"text":9341},{"id":9376,"depth":754,"text":9377},{"id":9411,"depth":754,"text":9412},{"id":9448,"depth":754,"text":9449},{"id":9481,"depth":754,"text":9482},{"id":9518,"depth":754,"text":9519},{"id":9551,"depth":754,"text":9552},{"id":9581,"depth":754,"text":9582},{"id":9611,"depth":754,"text":9612},{"id":9641,"depth":754,"text":9642},{"id":9671,"depth":754,"text":9672},{"id":9701,"depth":754,"text":9702},{"id":9735,"depth":754,"text":9736},{"id":9767,"depth":754,"text":9768},{"id":9799,"depth":754,"text":9800},{"id":9831,"depth":754,"text":9832},{"id":9882,"depth":754,"text":9883},{"id":9925,"depth":754,"text":9926},{"id":9951,"depth":754,"text":9952},{"id":9992,"depth":754,"text":9993},{"id":10044,"depth":754,"text":10045},{"id":10123,"depth":754,"text":10124},{"id":10174,"depth":754,"text":10175},{"id":10205,"depth":754,"text":10206},{"id":10235,"depth":754,"text":10236},{"id":10265,"depth":754,"text":10266},{"id":10315,"depth":754,"text":10316},{"id":10340,"depth":754,"text":10341},{"id":10390,"depth":754,"text":10391},{"id":10438,"depth":754,"text":10439},{"id":10496,"depth":754,"text":10497},{"id":10551,"depth":754,"text":10554},{"id":10595,"depth":754,"text":10596},{"id":10622,"depth":754,"text":10625},{"id":10659,"depth":754,"text":10660},{"id":10693,"depth":754,"text":11179},"Step 11: Point Apache At public_html",{"id":10727,"depth":754,"text":10728},{"id":10778,"depth":754,"text":10779},{"id":10830,"depth":754,"text":10831},{"id":10846,"depth":754,"text":10849},{"id":10874,"depth":754,"text":10877},{"id":10922,"depth":754,"text":10925},{"id":651,"depth":754,"text":652},{"id":717,"depth":754,"text":720},"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":8513,"description":11188},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[11198,11199,10468,11200,11201],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581681428]