[{"data":1,"prerenderedAt":11418},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository":3,"content-page-quiz:none":1140,"book-module-total-pages":1141,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":1142,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository":11417},{"id":4,"title":5,"audience":6,"body":7,"contentType":1116,"course":1117,"description":1118,"estimateBasis":1119,"estimatedDiscussionMinutes":1120,"estimatedLiveMinutes":1121,"estimatedTotalMinutes":1122,"extension":1123,"meta":1124,"module":1125,"navigation":1126,"order":1122,"path":1127,"promptAssist":1128,"seo":1129,"status":1130,"stem":1131,"tags":1132,"videoDuration":1135,"videoId":1136,"videoLink":1137,"videoTitle":1138,"week":1125,"__hash__":1139},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository.md","Add Instructor Template To Your Repository","student",{"type":8,"value":9,"toc":1086},"minimark",[10,49,104,133,168,201,251,345,389,434,480,526,602,663,738,793,870,942,975,1029,1055],[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 have:",[24,25,26,30,33,40,46],"ul",{},[27,28,29],"li",{},"Cloned course repository open in the terminal",[27,31,32],{},"Starter template copied into the repository root",[27,34,35,36],{},"Baseline commit on ",[37,38,39],"code",{},"Module01-Course-Template",[27,41,42,43],{},"Pull request merged into ",[37,44,45],{},"main",[27,47,48],{},"Clean working tree before moving on",[11,50,52,56],{"id":51,"level":14},"step-1-open-clone",[16,53,55],{"id":54},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[57,58,61,74],"two-col",{"gap":59,"left-width":60,"right-width":60},"lg","1fr",[62,63,65,68],"template",{"v-slot:left":64},"",[20,66,67],{},"Run:",[69,70],"code-snippet",{"language":71,"src":72,"label":73},"bash","\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",[62,75,76,79,84],{"v-slot:right":64},[20,77,78],{},"Example output:",[69,80],{"language":81,"src":82,"label":83},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt","example-output.txt",[24,85,86,92,98],{},[27,87,88,91],{},[37,89,90],{},"pwd",": current working directory",[27,93,94,97],{},[37,95,96],{},"git status",": current branch and file state",[27,99,100,101,103],{},"Important check: ",[37,102,90],{}," ends with your repository folder",[11,105,107,111,114,117],{"id":106,"level":14},"step-2-open-vscode",[16,108,110],{"id":109},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[20,112,113],{},"Run from inside the cloned repository folder:",[69,115],{"language":71,"src":116},"\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,118,119,124,130],{},[27,120,121,123],{},[37,122,37],{},": opens VS Code from the terminal",[27,125,126,129],{},[37,127,128],{},"."," means \"this current folder\"",[27,131,132],{},"VS Code should show your repository folder, not the parent folder",[11,134,136,140],{"id":135,"level":14},"step-3-download-template",[16,137,139],{"id":138},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[24,141,142,156,159,162,165],{},[27,143,144,145],{},"Open the instructor template repository",[24,146,147],{},[27,148,149],{},[150,151,155],"a",{"href":152,"rel":153},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[154],"nofollow","IT202-2026",[27,157,158],{},"Download the ZIP",[27,160,161],{},"Extract the ZIP",[27,163,164],{},"Copy scaffold contents into your repository root",[27,166,167],{},"See the slide below for the copy rule",[11,169,172,177,180,183,198],{"id":170,"level":171},"template-copy-rule","3",[173,174,176],"h3",{"id":175},"copy-rule","Copy Rule",[20,178,179],{},"Copy the contents of the extracted template folder",[20,181,182],{},"Do not copy:",[24,184,185,188,195],{},[27,186,187],{},"The extracted wrapper folder as one extra nested folder",[27,189,190,191,194],{},"The template repository's hidden ",[37,192,193],{},".git"," folder",[27,196,197],{},"Old files from a different semester",[20,199,200],{},"Repository root should contain the starter folders directly",[11,202,204,208,211,215],{"id":203,"level":14},"step-4-check-structure",[16,205,207],{"id":206},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[20,209,210],{},"After copying, repository root should look similar to:",[69,212],{"language":213,"src":214},"text","\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,216,217,223,232,248],{},[27,218,219,222],{},[37,220,221],{},"public_html"," should be directly inside your repository root",[27,224,225,226,229,230],{},"Module folders and ",[37,227,228],{},"project"," live inside ",[37,231,221],{},[27,233,234,237,238,241,242,245,246],{},[37,235,236],{},"lib",", ",[37,239,240],{},"partials",", and ",[37,243,244],{},"sql"," stay outside ",[37,247,221],{},[27,249,250],{},"See the slide below for the public\u002Fprivate folder boundary",[11,252,254,258,342],{"id":253,"level":171},"public-html-boundary",[173,255,257],{"id":256},"public-and-private-boundary","Public And Private Boundary",[24,259,260,294,317,322,327,333,339],{},[27,261,262,264,265],{},[37,263,221],{},": web root Apache can serve\n",[24,266,267,277,282,288],{},[27,268,269,272,273,276],{},[37,270,271],{},"m01"," through ",[37,274,275],{},"m10",": module practice folders",[27,278,279,281],{},[37,280,228],{},": course project folder",[27,283,284,287],{},[37,285,286],{},"index.php",": first browser entry point",[27,289,290,293],{},[37,291,292],{},"test_db.php",": database connection check",[27,295,296,298,299],{},[37,297,236],{},": reusable PHP helpers\n",[24,300,301,307],{},[27,302,303,306],{},[37,304,305],{},".env.sample",": example local config file",[27,308,309,312,313,316],{},[37,310,311],{},"config.php"," and ",[37,314,315],{},"db.php",": config and database helpers",[27,318,319,321],{},[37,320,240],{},": shared page pieces",[27,323,324,326],{},[37,325,244],{},": database setup scripts",[27,328,329,332],{},[37,330,331],{},"Dockerfile",": consistent runtime setup",[27,334,335,338],{},[37,336,337],{},"structure.md",": starter layout notes",[27,340,341],{},"Private folders should not be opened directly in the browser",[20,343,344],{},"Later server setup expects this folder boundary",[11,346,348,352],{"id":347,"level":14},"step-5-check-status",[16,349,351],{"id":350},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[57,353,354,362],{"gap":59,"left-width":60,"right-width":60},[62,355,356,358],{"v-slot:left":64},[20,357,67],{},[69,359],{"language":71,"src":360,"label":361},"\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",[62,363,364,367,370],{"v-slot:right":64},[20,365,366],{},"Expected idea:",[69,368],{"language":213,"src":369,"label":83},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[24,371,372,378,383,386],{},[27,373,374,377],{},[37,375,376],{},"git checkout -b",": create and move to a new branch",[27,379,380,381],{},"Branch name: ",[37,382,39],{},[27,384,385],{},"New files listed as untracked",[27,387,388],{},"No changes means likely wrong folder or copy missed",[11,390,392,396],{"id":391,"level":14},"step-6-stage",[16,393,395],{"id":394},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[57,397,398,406],{"gap":59,"left-width":60,"right-width":60},[62,399,400,402],{"v-slot:left":64},[20,401,67],{},[69,403],{"language":71,"src":404,"label":405},"\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",[62,407,408,411,429,431],{"v-slot:right":64},[20,409,410],{},"What this means:",[24,412,413,419,424],{},[27,414,415,418],{},[37,416,417],{},"git add",": choose files for the next commit",[27,420,421,423],{},[37,422,128],{}," means current folder and contents",[27,425,426,428],{},[37,427,96],{},": verify what is staged before committing",[20,430,366],{},[69,432],{"language":213,"src":433,"label":83},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,435,437,441],{"id":436,"level":14},"step-7-commit",[16,438,440],{"id":439},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[57,442,443,451],{"gap":59,"left-width":60,"right-width":60},[62,444,445,447],{"v-slot:left":64},[20,446,67],{},[69,448],{"language":71,"src":449,"label":450},"\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",[62,452,453,455,458],{"v-slot:right":64},[20,454,366],{},[69,456],{"language":213,"src":457,"label":83},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[24,459,460,466,477],{},[27,461,462,465],{},[37,463,464],{},"git commit",": save staged changes in local history",[27,467,468,471,472],{},[37,469,470],{},"-m",": commit message\n",[24,473,474],{},[27,475,476],{},"Message is required, even if empty",[27,478,479],{},"Baseline commit: starter state before custom work",[11,481,483,487],{"id":482,"level":14},"step-8-push",[16,484,486],{"id":485},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[57,488,489,497],{"gap":59,"left-width":60,"right-width":60},[62,490,491,493],{"v-slot:left":64},[20,492,67],{},[69,494],{"language":71,"src":495,"label":496},"\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",[62,498,499,501,504],{"v-slot:right":64},[20,500,366],{},[69,502],{"language":213,"src":503,"label":83},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[24,505,506,512,518,523],{},[27,507,508,511],{},[37,509,510],{},"origin",": GitHub remote",[27,513,514,517],{},[37,515,516],{},"-u",": remembers this branch's GitHub tracking branch",[27,519,520,522],{},[37,521,39],{},": branch being sent",[27,524,525],{},"Refresh GitHub after the push",[11,527,529,533],{"id":528,"level":14},"step-9-open-pull-request",[16,530,532],{"id":531},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[57,534,535,582],{"gap":59,"left-width":60,"right-width":60},[62,536,537,540],{"v-slot:left":64},[20,538,539],{},"In GitHub:",[24,541,542,545,564,569,574,577],{},[27,543,544],{},"Open your course repository",[27,546,547,548,552],{},"Click ",[549,550,551],"strong",{},"Compare & pull request",[24,553,554],{},[27,555,556,557,560,561],{},"Or use ",[549,558,559],{},"Pull requests"," -> ",[549,562,563],{},"New pull request",[27,565,566,567],{},"Set base branch to ",[37,568,45],{},[27,570,571,572],{},"Set compare branch to ",[37,573,39],{},[27,575,576],{},"Confirm the changed files are the starter template files",[27,578,547,579],{},[549,580,581],{},"Create pull request",[62,583,584,587,591],{"v-slot:right":64},[20,585,586],{},"Use a short title and description:",[69,588],{"language":213,"src":589,"label":590},"\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,592,593,596,599],{},[27,594,595],{},"Base receives the changes",[27,597,598],{},"Compare contains your branch work",[27,600,601],{},"If base and compare are reversed, do not create the pull request",[11,603,605,611],{"id":604,"level":14},"step-10-merge-sync-main",[16,606,608,609],{"id":607},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[37,610,45],{},[57,612,613,636],{"gap":59,"left-width":60,"right-width":60},[62,614,615,617,629,632],{"v-slot:left":64},[20,616,539],{},[24,618,619,624],{},[27,620,547,621],{},[549,622,623],{},"Merge pull request",[27,625,547,626],{},[549,627,628],{},"Confirm merge",[20,630,631],{},"Then run:",[69,633],{"language":71,"src":634,"label":635},"\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",[62,637,638,640,643],{"v-slot:right":64},[20,639,366],{},[69,641],{"language":213,"src":642,"label":83},"\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,644,645,651,657],{},[27,646,647,650],{},[37,648,649],{},"git checkout main",": return to the main branch",[27,652,653,656],{},[37,654,655],{},"git pull origin main",": download the merged template files",[27,658,659,660,662],{},"Continue only when local ",[37,661,45],{}," is clean",[11,664,666,672],{"id":665,"level":14},"step-11-create-local-env",[16,667,668,669],{"id":665},"Step 11: Create Local ",[37,670,671],{},".env",[57,673,674,697],{"gap":59,"left-width":60,"right-width":60},[62,675,676,679,683],{"v-slot:left":64},[20,677,678],{},"Run from the repository root:",[69,680],{"language":71,"src":681,"label":682},"\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,684,685],{},[27,686,687,688,691,692],{},"Get ",[37,689,690],{},"DB_URL"," from ",[150,693,696],{"href":694,"rel":695},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[154],"courses.ethereallab.app\u002Fdatabase",[62,698,699,702,707],{"v-slot:right":64},[20,700,701],{},"Fill in values similar to:",[69,703],{"language":704,"src":705,"label":706},"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,708,709,714,720,723,728,733],{},[27,710,711,713],{},[37,712,671],{}," stores local secrets",[27,715,716,717,719],{},"Keep ",[37,718,671],{}," on your computer only",[27,721,722],{},"Do not commit your real connection string",[27,724,725,726],{},"Paste the generated database connection string as ",[37,727,690],{},[27,729,730,732],{},[37,731,311],{}," loads local or hosted environment variables",[27,734,735,736],{},"Do not paste secrets directly into ",[37,737,311],{},[11,739,741,745],{"id":740,"level":14},"step-12-test-local-db",[16,742,744],{"id":743},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[57,746,747,755],{"gap":59,"left-width":60,"right-width":60},[62,748,749,751],{"v-slot:left":64},[20,750,678],{},[69,752],{"language":71,"src":753,"label":754},"\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",[62,756,757,760,764],{"v-slot:right":64},[20,758,759],{},"Then open:",[69,761],{"language":213,"src":762,"label":763},"\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,765,766,772,778,786],{},[27,767,768,771],{},[37,769,770],{},"php -S",": starts PHP's built-in local server",[27,773,774,777],{},[37,775,776],{},"-t public_html",": serves the course web root",[27,779,780,782,783,785],{},[37,781,292],{},": confirms PHP can read ",[37,784,671],{}," and connect to MySQL",[27,787,788,789,792],{},"Stop the server with ",[37,790,791],{},"Ctrl+C"," when finished",[11,794,796,804,810],{"id":795,"level":14},"step-13-enable-pdo-mysql",[16,797,799,800,803],{"id":798},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[37,801,802],{},"pdo_mysql"," If Needed",[20,805,806,807,128],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[37,808,809],{},"apt",[57,811,812,844],{"gap":59,"left-width":60,"right-width":60},[62,813,814,817,821,824],{"v-slot:left":64},[20,815,816],{},"Find the PHP folder:",[69,818],{"language":71,"src":819,"label":820},"\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,822,823],{},"In that folder:",[24,825,826,832,838],{},[27,827,828,829],{},"Find ",[37,830,831],{},"php.ini-development",[27,833,834,835],{},"Copy it as ",[37,836,837],{},"php.ini",[27,839,840,841,843],{},"Open ",[37,842,837],{}," in your editor",[62,845,846,849,853,856,860],{"v-slot:right":64},[20,847,848],{},"Uncomment these lines:",[69,850],{"language":851,"src":852,"label":837},"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,854,855],{},"Mac\u002FLinux usually use:",[69,857],{"language":71,"src":858,"label":859},"\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,861,862,867],{},[27,863,864,865],{},"Restart the php dev server after changing ",[37,866,837],{},[27,868,869],{},"Run Step 12 again after enabling the extension",[11,871,873,877,880],{"id":872,"level":14},"quick-check-final",[16,874,876],{"id":875},"quick-check","Quick Check",[20,878,879],{},"Confirm all of these:",[24,881,882,885,893,896,902,911,917,922,927,933],{},[27,883,884],{},"GitHub shows the starter files",[27,886,887,888,890,891],{},"GitHub shows a pull request from ",[37,889,39],{}," into ",[37,892,45],{},[27,894,895],{},"The pull request is merged",[27,897,898,899,901],{},"Local ",[37,900,45],{}," says the working tree is clean",[27,903,904,272,907,910],{},[37,905,906],{},"public_html\u002Fm01",[37,908,909],{},"public_html\u002Fm10"," exist",[27,912,913,916],{},[37,914,915],{},"public_html\u002Fproject"," exists",[27,918,919,921],{},[37,920,221],{}," is not nested inside another accidental folder",[27,923,924,926],{},[37,925,706],{}," exists locally and is not committed with real secrets",[27,928,929,932],{},[37,930,931],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[27,934,935,936,938,939,941],{},"Windows PHP has ",[37,937,802],{}," enabled if ",[37,940,292],{}," reports a missing driver",[11,943,945,949,951,954,964],{"id":944,"level":14},"reset-check",[16,946,948],{"id":947},"if-something-looks-wrong","If Something Looks Wrong",[20,950,67],{},[69,952],{"language":71,"src":953},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[955,956,957],"blockquote",{},[20,958,959,960,963],{},"Tip: ",[37,961,962],{},"git rev-parse --show-toplevel"," prints the repository root when your current folder is inside a Git repository",[24,965,966,969,972],{},[27,967,968],{},"Output should point to your course repository",[27,970,971],{},"If it points somewhere else, move folders before continuing",[27,973,974],{},"Avoid cloning inside another cloned repository",[11,976,978,981],{"id":977,"level":14},"common-mistakes",[16,979,980],{"id":977},"Common Mistakes",[24,982,983,986,989,994,997,1000,1005,1015,1020,1023],{},[27,984,985],{},"Opening the parent folder instead of the repository root",[27,987,988],{},"Copying the instructor template folder as a nested folder",[27,990,991,992,194],{},"Copying the template ",[37,993,193],{},[27,995,996],{},"Keeping the downloaded ZIP inside the repository",[27,998,999],{},"Re-cloning the repository instead of opening the existing clone",[27,1001,1002,1003],{},"Putting module folders outside ",[37,1004,221],{},[27,1006,1007,1008,1010,1011,1014],{},"Renaming ",[37,1009,271],{}," to ",[37,1012,1013],{},"M1"," or mixing folder casing",[27,1016,1017,1018],{},"Doing template work directly on ",[37,1019,45],{},[27,1021,1022],{},"Reversing base and compare branches in the pull request",[27,1024,1025,1026,1028],{},"Forgetting to sync local ",[37,1027,45],{}," after the pull request is merged",[11,1030,1032,1035],{"id":1031,"level":14},"key-terms",[16,1033,1034],{"id":1031},"Key Terms",[24,1036,1037,1040,1043,1046,1049,1052],{},[27,1038,1039],{},"Repository root: top folder of the cloned project",[27,1041,1042],{},"Baseline: starter state before custom work begins",[27,1044,1045],{},"Pull request: GitHub review page used to merge branch work",[27,1047,1048],{},"Web root: folder served to the browser",[27,1050,1051],{},"Scaffold: starter folders that organize future work",[27,1053,1054],{},"Staging: choosing files for the next commit",[11,1056,1058,1061,1064],{"id":1057,"level":14},"summary",[16,1059,1060],{"id":1057},"Summary",[20,1062,1063],{},"Before leaving this presentation, confirm the following:",[24,1065,1066,1069,1072,1075,1081],{},[27,1067,1068],{},"You still have one clone for your repository",[27,1070,1071],{},"Your VS Code is able to open directly to your repository",[27,1073,1074],{},"Your repository has the full starter baseline correctly structured",[27,1076,1077,1078,1080],{},"GitHub remote ",[37,1079,45],{}," has the baseline content",[27,1082,898,1083,1085],{},[37,1084,45],{}," was synchronized",{"title":64,"searchDepth":1087,"depth":1087,"links":1088},2,[1089,1090,1091,1092,1096,1099,1100,1101,1102,1103,1104,1106,1108,1109,1111,1112,1113,1114,1115],{"id":13,"depth":1087,"text":18},{"id":54,"depth":1087,"text":55},{"id":109,"depth":1087,"text":110},{"id":138,"depth":1087,"text":139,"children":1093},[1094],{"id":175,"depth":1095,"text":176},3,{"id":206,"depth":1087,"text":207,"children":1097},[1098],{"id":256,"depth":1095,"text":257},{"id":350,"depth":1087,"text":351},{"id":394,"depth":1087,"text":395},{"id":439,"depth":1087,"text":440},{"id":485,"depth":1087,"text":486},{"id":531,"depth":1087,"text":532},{"id":607,"depth":1087,"text":1105},"Step 10: Merge And Sync main",{"id":665,"depth":1087,"text":1107},"Step 11: Create Local .env",{"id":743,"depth":1087,"text":744},{"id":798,"depth":1087,"text":1110},"Step 13: Enable pdo_mysql If Needed",{"id":875,"depth":1087,"text":876},{"id":947,"depth":1087,"text":948},{"id":977,"depth":1087,"text":980},{"id":1031,"depth":1087,"text":1034},{"id":1057,"depth":1087,"text":1060},"presentation","Internet Applications","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.","15","45","60","md",{},"1",true,"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",false,{"title":5,"description":1118},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[1133,62,1134],"repository","git","47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",null,[],[1143,1639,2705,3589,4678,5608,6397,7170,7896,8721],{"id":1144,"title":1145,"audience":6,"body":1146,"contentType":1116,"course":1117,"description":1619,"estimateBasis":1620,"estimatedDiscussionMinutes":1621,"estimatedLiveMinutes":1622,"estimatedTotalMinutes":1623,"extension":1123,"meta":1624,"module":1125,"navigation":1126,"order":1625,"path":1626,"promptAssist":1128,"seo":1627,"status":1130,"stem":1628,"tags":1629,"videoDuration":1634,"videoId":1635,"videoLink":1636,"videoTitle":1637,"week":1125,"__hash__":1638},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":1147,"toc":1604},[1148,1182,1222,1268,1317,1365,1398,1460,1501,1551,1578],[11,1149,1151,1155,1169],{"id":1150,"level":14},"learn-courses-flow",[16,1152,1154],{"id":1153},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[24,1156,1157,1160,1163,1166],{},[27,1158,1159],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[27,1161,1162],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[27,1164,1165],{},"The goal is to keep tasks clear and objective for students and grading",[27,1167,1168],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[20,1170,1171,1172,1176,1177,1181],{},"NOTE: Summer 2026 the previous Learn Platform (",[150,1173,1174],{"href":1174,"rel":1175},"https:\u002F\u002Flearn.ethereallab.app",[154],") has been replaced by Learn Courses Platform (",[150,1178,1179],{"href":1179,"rel":1180},"https:\u002F\u002Fcourses.ethereallab.app",[154],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,1183,1185,1188,1191,1219],{"id":1184,"level":14},"learn-courses-title",[16,1186,1145],{"id":1187},"learn-courses-platform-and-discord",[20,1189,1190],{},"How to join:",[24,1192,1193,1199,1207,1210,1213,1216],{},[27,1194,1195,1196],{},"Visit the platform ",[150,1197,1179],{"href":1179,"rel":1198},[154],[27,1200,1201,1202],{},"Sign in with your NJIT email\n",[24,1203,1204],{},[27,1205,1206],{},"If you're in the Canvas course, you should automatically get synced to this platform",[27,1208,1209],{},"Visit your Profile page",[27,1211,1212],{},"Associate your Discord account",[27,1214,1215],{},"Join the course Discord server",[27,1217,1218],{},"Verify that your course channels appear on Discord",[20,1220,1221],{},"You can follow the steps on the below slides for guidance",[11,1223,1225,1228],{"id":1224,"level":171},"visit-learn-courses",[16,1226,1227],{"id":1224},"Visit Learn Courses",[57,1229,1230,1258],{"gap":59,"left-width":60,"right-width":60},[62,1231,1232,1235,1240],{"v-slot:left":64},[20,1233,1234],{},"Go to:",[20,1236,1237],{},[150,1238,1179],{"href":1179,"rel":1239},[154],[24,1241,1242,1249,1252,1255],{},[27,1243,1244,1245,1248],{},"Click the ",[549,1246,1247],{},"Login"," button",[27,1250,1251],{},"Use your NJIT email",[27,1253,1254],{},"Only NJIT accounts are allowed",[27,1256,1257],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[62,1259,1260],{"v-slot:right":64},[20,1261,1262],{},[1263,1264],"img",{"alt":1265,"src":1266,"variant":1267},"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,1269,1271,1274],{"id":1270,"level":171},"associate-discord-name",[16,1272,1273],{"id":1270},"Associate Discord Name",[57,1275,1276,1301],{"gap":59,"left-width":60,"right-width":60},[62,1277,1278,1281,1298],{"v-slot:left":64},[20,1279,1280],{},"On Learn Courses:",[1282,1283,1284,1287,1292,1295],"ol",{},[27,1285,1286],{},"Open your Profile",[27,1288,547,1289],{},[549,1290,1291],{},"Refresh Discord Username",[27,1293,1294],{},"Authorize the Discord prompt",[27,1296,1297],{},"After the success message appears, save your profile",[20,1299,1300],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[62,1302,1303,1310],{"v-slot:right":64},[20,1304,1305],{},[1263,1306],{"alt":1307,"src":1308,"variant":1267,"max-height":1309},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[20,1311,1312],{},[1263,1313],{"alt":1314,"src":1315,"variant":1267,"max-height":1316},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,1318,1320,1323],{"id":1319,"level":171},"authorize-discord",[16,1321,1322],{"id":1319},"Authorize Discord",[57,1324,1325,1349],{"gap":59,"left-width":60,"right-width":60},[62,1326,1327,1330],{"v-slot:left":64},[20,1328,1329],{},"Discord will ask whether Learn Courses can access your Discord account.",[24,1331,1332,1335,1340,1343,1346],{},[27,1333,1334],{},"Confirm you are signed in to the correct Discord account",[27,1336,547,1337],{},[549,1338,1339],{},"Authorize",[27,1341,1342],{},"Return to Learn Courses",[27,1344,1345],{},"Look for the success message",[27,1347,1348],{},"Save the profile change",[62,1350,1351,1358],{"v-slot:right":64},[20,1352,1353],{},[1263,1354],{"alt":1355,"src":1356,"variant":1267,"max-height":1357},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[20,1359,1360],{},[1263,1361],{"alt":1362,"src":1363,"variant":1267,"max-height":1364},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,1366,1368,1371,1374,1380,1387],{"id":1367,"level":171},"join-the-channel",[16,1369,1370],{"id":1367},"Join The Channel",[20,1372,1373],{},"Use the Discord link provided on Canvas, or use:",[20,1375,1376],{},[150,1377,1378],{"href":1378,"rel":1379},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[154],[20,1381,1382,1383,1386],{},"This should send you to the ",[37,1384,1385],{},"access-channel"," channel.",[24,1388,1389,1392,1395],{},[27,1390,1391],{},"Other channels are protected by a bot",[27,1393,1394],{},"Messages may be blocked until your name and role are set",[27,1396,1397],{},"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,1399,1401,1404],{"id":1400,"level":14},"verify-with-quackbot",[16,1402,1403],{"id":1400},"Verify With QuackBot",[57,1405,1406,1451],{"gap":59,"left-width":60,"right-width":60},[62,1407,1408,1420,1426,1431,1434,1448],{"v-slot:left":64},[24,1409,1410,1413],{},[27,1411,1412],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[27,1414,1415,1416,1419],{},"If you don't see the proper semester category (i.e., ",[37,1417,1418],{},"summer-2026",") or the expected channels you can do the below action",[20,1421,1422,1423,1425],{},"In ",[37,1424,1385],{},", enter:",[20,1427,1428],{},[37,1429,1430],{},"@QuackBot",[20,1432,1433],{},"QuackBot will:",[24,1435,1436,1439,1442,1445],{},[27,1437,1438],{},"Verify your account",[27,1440,1441],{},"Pull in your name and section",[27,1443,1444],{},"Apply your class role",[27,1446,1447],{},"Update your server nickname",[20,1449,1450],{},"This does not change your real Discord username.",[62,1452,1453],{"v-slot:right":64},[20,1454,1455],{},[1263,1456],{"alt":1457,"src":1458,"variant":1267,"max-height":1459},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,1461,1463,1467,1470,1481,1485],{"id":1462,"level":14},"welcome-and-potential-issues",[16,1464,1466],{"id":1465},"welcome","Welcome",[20,1468,1469],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[24,1471,1472,1475,1478],{},[27,1473,1474],{},"It should appear after the general channels",[27,1476,1477],{},"It should include one or more channels for your active courses",[27,1479,1480],{},"Use the correct course channel for class questions and discussion",[173,1482,1484],{"id":1483},"potential-issues","Potential Issues",[24,1486,1487,1490],{},[27,1488,1489],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[27,1491,1492,1493,1496],{},"If there is an issue, email the instructor or DM ",[37,1494,1495],{},"MattToegel",[24,1497,1498],{},[27,1499,1500],{},"Some Discord privacy settings may require a friend request before DMs work",[11,1502,1504,1507],{"id":1503,"level":14},"general-conduct",[16,1505,1506],{"id":1503},"General Conduct",[24,1508,1509,1512,1515,1526,1529,1537,1545,1548],{},[27,1510,1511],{},"Use class-related channels for questions and discussion",[27,1513,1514],{},"Ask general course questions in the channel instead of DM when possible",[27,1516,1517,1518],{},"Do not post screenshots of in-progress assignment solutions\n",[24,1519,1520,1523],{},[27,1521,1522],{},"This would be more ideal for a DM",[27,1524,1525],{},"If you see posted solution-like items don't assume they're correct",[27,1527,1528],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[27,1530,1531,1532],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[24,1533,1534],{},[27,1535,1536],{},"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,1538,1539,1540],{},"Keep off-topic items out of class channels\n",[24,1541,1542],{},[27,1543,1544],{},"There are plenty of categorized channels to use and I can always make more",[27,1546,1547],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[27,1549,1550],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,1552,1553,1555,1558],{"id":875,"level":14},[16,1554,876],{"id":875},[20,1556,1557],{},"Before continuing, confirm:",[24,1559,1560,1563,1566,1569,1572,1575],{},[27,1561,1562],{},"You can sign in to Learn Courses with your NJIT email",[27,1564,1565],{},"Your profile is saved",[27,1567,1568],{},"Discord is associated with your Learn Courses profile",[27,1570,1571],{},"You joined the Discord server",[27,1573,1574],{},"QuackBot applied your course role",[27,1576,1577],{},"You can see the correct course channel",[11,1579,1580,1582],{"id":1057,"level":14},[16,1581,1060],{"id":1057},[24,1583,1584,1587,1595,1598,1601],{},[27,1585,1586],{},"Learn Courses supports course tools and course-specific setup",[27,1588,1589,1590],{},"Canvas remains the official assignment, grade, and course hub\n",[24,1591,1592],{},[27,1593,1594],{},"All necessary items will be linked on Canvas",[27,1596,1597],{},"Discord is the preferred quick communication channel",[27,1599,1600],{},"QuackBot connects your Discord account to the correct course role",[27,1602,1603],{},"Good course communication keeps help requests specific and protects private information",{"title":64,"searchDepth":1087,"depth":1087,"links":1605},[1606,1607,1608,1609,1610,1611,1612,1613,1616,1617,1618],{"id":1153,"depth":1087,"text":1154},{"id":1187,"depth":1087,"text":1145},{"id":1224,"depth":1087,"text":1227},{"id":1270,"depth":1087,"text":1273},{"id":1319,"depth":1087,"text":1322},{"id":1367,"depth":1087,"text":1370},{"id":1400,"depth":1087,"text":1403},{"id":1465,"depth":1087,"text":1466,"children":1614},[1615],{"id":1483,"depth":1095,"text":1484},{"id":1503,"depth":1087,"text":1506},{"id":875,"depth":1087,"text":876},{"id":1057,"depth":1087,"text":1060},"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":1145,"description":1619},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[1630,1631,1632,1633],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":1640,"title":1641,"audience":6,"body":1642,"contentType":1116,"course":1117,"description":2690,"estimateBasis":2691,"estimatedDiscussionMinutes":1621,"estimatedLiveMinutes":1121,"estimatedTotalMinutes":2692,"extension":1123,"meta":2693,"module":1125,"navigation":1126,"order":1621,"path":2694,"promptAssist":1128,"seo":2695,"status":1130,"stem":2696,"tags":2697,"videoDuration":2701,"videoId":2702,"videoLink":2703,"videoTitle":1641,"week":1125,"__hash__":2704},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":1643,"toc":2656},[1644,1702,1737,1769,1830,1896,1946,1972,1989,2027,2055,2076,2111,2133,2205,2228,2273,2336,2388,2416,2436,2465,2503,2532,2542,2609],[11,1645,1647,1651],{"id":1646,"level":14},"why-cli-first",[16,1648,1650],{"id":1649},"why-cli-comes-first","Why CLI Comes First",[24,1652,1653,1661,1669,1683,1691],{},[27,1654,1655,1656],{},"Common language for setup and developer tools\n",[24,1657,1658],{},[27,1659,1660],{},"Git, servers, package installs, deployment logs",[27,1662,1663,1664],{},"Works when there is no full desktop\n",[24,1665,1666],{},[27,1667,1668],{},"SSH, Ubuntu Server, minimal system access",[27,1670,1671,1672],{},"Direct check of what the computer sees\n",[24,1673,1674,1677,1680],{},[27,1675,1676],{},"Current folder",[27,1678,1679],{},"Files and permissions",[27,1681,1682],{},"Command output",[27,1684,1685,1686],{},"Repeatable steps beat guessing through menus\n",[24,1687,1688],{},[27,1689,1690],{},"Run a command, read output, adjust",[27,1692,1693,1694],{},"Location still matters\n",[24,1695,1696,1699],{},[27,1697,1698],{},"Wrong folder can make correct commands fail",[27,1700,1701],{},"Or create files in the wrong place",[11,1703,1705,1708,1711],{"id":1704,"level":14},"goal",[16,1706,1707],{"id":1704},"Goal",[20,1709,1710],{},"Build the command-line habits that make setup work predictable:",[24,1712,1713,1716,1719,1731,1734],{},[27,1714,1715],{},"Know what folder the terminal is using",[27,1717,1718],{},"Read file and folder lists before moving",[27,1720,1721,1722,237,1725,241,1728],{},"Recognize common flags like ",[37,1723,1724],{},"-a",[37,1726,1727],{},"-r",[37,1729,1730],{},"-l",[27,1732,1733],{},"Make small file changes and verify them",[27,1735,1736],{},"Stop safely when output does not match the lesson",[11,1738,1740,1743,1746,1766],{"id":1739,"level":14},"before-you-start",[16,1741,1742],{"id":1739},"Before You Start",[20,1744,1745],{},"Run these commands on your host computer",[24,1747,1748,1760,1763],{},[27,1749,1750,1751],{},"Windows: Git Bash",[24,1752,1753],{},[27,1754,1755,1756],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[150,1757,1759],{"href":1758},"\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,1761,1762],{},"Apple macOS: Terminal",[27,1764,1765],{},"Linux: Terminal",[20,1767,1768],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1770,1772,1776],{"id":1771,"level":14},"working-directory",[16,1773,1775],{"id":1774},"the-main-idea","The Main Idea",[24,1777,1778,1789,1799,1822],{},[27,1779,1780,1781],{},"Terminal commands run from one folder at a time\n",[24,1782,1783],{},[27,1784,1785,1786],{},"That folder is the ",[549,1787,1788],{},"working directory",[27,1790,1791,1793,1794],{},[37,1792,90],{},": print working directory\n",[24,1795,1796],{},[27,1797,1798],{},"Shows the full path to the folder your terminal is using",[27,1800,1801,1802],{},"Fresh terminal usually starts in your home folder\n",[24,1803,1804,1810,1816],{},[27,1805,1806,1807],{},"Windows Git Bash: ",[37,1808,1809],{},"\u002Fc\u002FUsers\u002Fyour-username",[27,1811,1812,1813],{},"Apple macOS: ",[37,1814,1815],{},"\u002FUsers\u002Fyour-username",[27,1817,1818,1819],{},"Linux: ",[37,1820,1821],{},"\u002Fhome\u002Fyour-username",[27,1823,1824,1825],{},"Commands from this lesson start from the working directory\n",[24,1826,1827],{},[27,1828,1829],{},"Unless you give a different path",[11,1831,1833,1836,1839,1890],{"id":1832,"level":14},"paths-relative-and-absolute",[16,1834,1835],{"id":1832},"Paths: Relative And Absolute",[20,1837,1838],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[24,1840,1841,1847,1853,1858,1884],{},[27,1842,1843,1844],{},"Relative path: starts from the working directory, like ",[37,1845,1846],{},"public\u002Findex.php",[27,1848,1849,1850],{},"Absolute path: starts from the system root, like ",[37,1851,1852],{},"\u002Fhome\u002Fstudent\u002Fproject",[27,1854,1855,1857],{},[37,1856,128],{}," means the current folder",[27,1859,1860,1863,1864],{},[37,1861,1862],{},".."," means the parent folder\n",[24,1865,1866,1872,1878],{},[27,1867,1868,1871],{},[37,1869,1870],{},"..\u002F.."," goes up two folders",[27,1873,1874,1875],{},"Example: ",[37,1876,1877],{},"cd ..\u002F..",[27,1879,1880,1883],{},[37,1881,1882],{},"..."," is not a shortcut",[27,1885,1886,1889],{},[37,1887,1888],{},"~"," means your home folder",[20,1891,1892,1893,1895],{},"If a command affects the wrong place, check ",[37,1894,90],{}," first, then check the path you typed",[11,1897,1899,1902,1905,1923,1926],{"id":1898,"level":14},"flags-options-and-arguments",[16,1900,1901],{"id":1898},"Flags, Options, And Arguments",[20,1903,1904],{},"Commands usually follow this shape:",[24,1906,1907,1913,1918],{},[27,1908,1909,1910],{},"Command: what to do, like ",[37,1911,1912],{},"ls",[27,1914,1915,1916],{},"Flag or option: how to do it, like ",[37,1917,1724],{},[27,1919,1920,1921],{},"Argument: what to do it to, like ",[37,1922,221],{},[20,1924,1925],{},"Examples:",[24,1927,1928,1934,1940],{},[27,1929,1930,1933],{},[37,1931,1932],{},"ls -a"," shows hidden files",[27,1935,1936,1939],{},[37,1937,1938],{},"cp -r folder backup-folder"," copies a folder",[27,1941,1942,1945],{},[37,1943,1944],{},"nano -l file.txt"," opens with line numbers",[11,1947,1949,1953,1956,1967],{"id":1948,"level":14},"practice-loop",[16,1950,1952],{"id":1951},"practice-1-location-and-paths","Practice 1: Location And Paths",[20,1954,1955],{},"For each command, use the same pattern:",[1282,1957,1958,1961,1964],{},[27,1959,1960],{},"Run one command",[27,1962,1963],{},"Read the output",[27,1965,1966],{},"Confirm the folder or file changed the way you expected",[24,1968,1969],{},[27,1970,1971],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1973,1975,1978,1980,1983,1986],{"id":1974,"level":171},"step-1-confirm-where-you-are",[16,1976,1977],{"id":1974},"Step 1: Confirm Where You Are",[20,1979,67],{},[69,1981],{"language":71,"src":1982},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[20,1984,1985],{},"Expected result: a folder path",[20,1987,1988],{},"If you see a path, the terminal is working and you know your current location",[11,1990,1992,1995,1997,2000,2003,2006,2009],{"id":1991,"level":171},"step-2-list-files",[16,1993,1994],{"id":1991},"Step 2: List Files",[20,1996,67],{},[69,1998],{"language":71,"src":1999},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[20,2001,2002],{},"Expected result: file and folder names from your current location",[20,2004,2005],{},"For hidden files and details too, run:",[69,2007],{"language":71,"src":2008},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[24,2010,2011,2016,2021],{},[27,2012,2013,2015],{},[37,2014,1724],{}," includes hidden files",[27,2017,2018,2020],{},[37,2019,1730],{}," uses a long listing",[27,2022,2023,2026],{},[37,2024,2025],{},"-la"," combines both",[11,2028,2030,2033,2036,2039,2046,2052],{"id":2029,"level":171},"step-3-change-folders",[16,2031,2032],{"id":2029},"Step 3: Change Folders",[20,2034,2035],{},"Start from your home folder, then move up and back",[69,2037],{"language":71,"src":2038},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[20,2040,2041,2042,2045],{},"This avoids assuming your computer has a specific folder like ",[37,2043,2044],{},"Documents"," in the current location",[20,2047,2048,2049,2051],{},"When you move into a named folder later, run ",[37,2050,1912],{}," first and pick a folder that actually appears in the list",[20,2053,2054],{},"If a path has spaces, wrap it in quotes",[11,2056,2058,2062,2064,2067],{"id":2057,"level":171},"step-4-create-practice-folder",[16,2059,2061],{"id":2060},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[20,2063,67],{},[69,2065],{"language":71,"src":2066},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[20,2068,2069,2070,2072,2073],{},"Expected result: ",[37,2071,90],{}," ends with ",[37,2074,2075],{},"cli-practice",[11,2077,2079,2083,2085,2088,2091],{"id":2078,"level":171},"step-5-create-and-read-file",[16,2080,2082],{"id":2081},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[20,2084,67],{},[69,2086],{"language":71,"src":2087},"\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,2089,2090],{},"What this command does:",[24,2092,2093,2099,2105],{},[27,2094,2095,2098],{},[37,2096,2097],{},"echo"," prepares text for the terminal",[27,2100,2101,2104],{},[37,2102,2103],{},">"," redirects that text into a file instead of printing it on screen",[27,2106,2107,2110],{},[37,2108,2109],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,2112,2114,2118,2121,2124,2130],{"id":2113,"level":171},"step-5-read-file-back",[173,2115,2117],{"id":2116},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[20,2119,2120],{},"Then read it back:",[69,2122],{"language":71,"src":2123},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[20,2125,2126,2129],{},[37,2127,2128],{},"cat"," prints file contents in the terminal",[20,2131,2132],{},"Expected result: the terminal prints the text you wrote",[11,2134,2136,2140,2142,2151,2154,2180,2183],{"id":2135,"level":14},"file-management-loop",[16,2137,2139],{"id":2138},"practice-2-file-management","Practice 2: File Management",[20,2141,1955],{},[1282,2143,2144,2146,2148],{},[27,2145,1960],{},[27,2147,1963],{},[27,2149,2150],{},"Confirm the file changed the way you expected",[20,2152,2153],{},"Commands in this practice:",[24,2155,2156,2162,2168,2174],{},[27,2157,2158,2161],{},[37,2159,2160],{},"touch"," creates an empty file",[27,2163,2164,2167],{},[37,2165,2166],{},"cp"," copies a file or folder",[27,2169,2170,2173],{},[37,2171,2172],{},"mv"," moves or renames",[27,2175,2176,2179],{},[37,2177,2178],{},"rm"," deletes",[20,2181,2182],{},"Important flags:",[24,2184,2185,2191,2197,2203],{},[27,2186,2187,2190],{},[37,2188,2189],{},"cp -r"," copies folders",[27,2192,2193,2196],{},[37,2194,2195],{},"rm -r"," deletes folders",[27,2198,2199,2202],{},[37,2200,2201],{},"rm -f"," forces deletion",[27,2204,1971],{},[11,2206,2208,2212,2214,2217,2222],{"id":2207,"level":171},"practice-2-step-1-create-empty-file",[16,2209,2211],{"id":2210},"step-1-create-an-empty-file","Step 1: Create An Empty File",[20,2213,67],{},[69,2215],{"language":71,"src":2216},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[20,2218,2219,2221],{},[37,2220,2160],{}," creates an empty file, or updates the timestamp if the file already exists",[20,2223,2069,2224,2227],{},[37,2225,2226],{},"practice-empty.txt"," appears in the folder list",[11,2229,2231,2235,2237,2240,2243,2249,2262],{"id":2230,"level":171},"practice-2-step-2-copy-rename-and-delete",[16,2232,2234],{"id":2233},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[20,2236,67],{},[69,2238],{"language":71,"src":2239},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[20,2241,2242],{},"Expected result: the backup is copied, renamed, then removed",[20,2244,2245,2246,2248],{},"Use ",[37,2247,2178],{}," carefully. Deleting from the terminal usually skips the recycle bin",[24,2250,2251,2256],{},[27,2252,2253,2255],{},[37,2254,1727],{},": recursive, includes folders and everything inside them",[27,2257,2258,2261],{},[37,2259,2260],{},"-f",": force, skips many confirmation prompts",[2263,2264,2266],"alert",{"color":2265},"red",[20,2267,2268,2269,2272],{},"Never run ",[37,2270,2271],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,2274,2276,2280,2283,2301,2306,2311,2331],{"id":2275,"level":14},"terminal-editors",[16,2277,2279],{"id":2278},"practice-3-terminal-editors","Practice 3: Terminal Editors",[20,2281,2282],{},"Sometimes you need to edit a file from a terminal",[24,2284,2285,2291],{},[27,2286,2287,2290],{},[37,2288,2289],{},"nano"," is beginner-friendly",[27,2292,2293,2296,2297,2300],{},[37,2294,2295],{},"vi"," or ",[37,2298,2299],{},"vim"," is common on servers but has a learning curve",[20,2302,2245,2303,2305],{},[37,2304,2289],{}," for this course unless a lesson says otherwise",[20,2307,2245,2308,2310],{},[37,2309,1944],{}," when line numbers would help",[20,2312,2313,2314,2296,2316,2318,2319,2322,2323,2326,2327,2330],{},"If you accidentally open ",[37,2315,2295],{},[37,2317,2299],{},", press ",[37,2320,2321],{},"Esc",", type ",[37,2324,2325],{},":q",", and press ",[37,2328,2329],{},"Enter"," to exit without saving",[24,2332,2333],{},[27,2334,2335],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,2337,2339,2344,2346,2349,2354,2376],{"id":2338,"level":171},"edit-with-nano",[16,2340,2341,2342],{"id":2338},"Edit With ",[37,2343,2289],{},[20,2345,67],{},[69,2347],{"language":71,"src":2348},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[20,2350,1422,2351,2353],{},[37,2352,2289],{},":",[24,2355,2356,2359,2366,2370],{},[27,2357,2358],{},"Type a short note",[27,2360,2361,2362,2365],{},"Press ",[37,2363,2364],{},"Ctrl+O"," to save",[27,2367,2361,2368],{},[37,2369,2329],{},[27,2371,2361,2372,2375],{},[37,2373,2374],{},"Ctrl+X"," to exit",[20,2377,2378,2379,2381,2382,2322,2384,2326,2386],{},"If you open ",[37,2380,2295],{}," by mistake, press ",[37,2383,2321],{},[37,2385,2325],{},[37,2387,2329],{},[11,2389,2391,2397,2402,2405,2408,2411],{"id":2390,"level":14},"sudo-and-permission-boundaries",[16,2392,2393,2396],{"id":2390},[37,2394,2395],{},"sudo"," And Permission Boundaries",[20,2398,2399,2401],{},[37,2400,2395],{}," runs a command with elevated permissions",[20,2403,2404],{},"Use it only when a setup lesson explicitly says to use it",[20,2406,2407],{},"Example:",[69,2409],{"language":71,"src":2410},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[24,2412,2413],{},[27,2414,2415],{},"See the slide below for supporting examples and follow-up details",[11,2417,2419,2424,2430],{"id":2418,"level":171},"sudo-by-operating-system",[173,2420,2421,2423],{"id":2418},[37,2422,2395],{}," By Operating System",[20,2425,2426,2427,2429],{},"On Linux and macOS, ",[37,2428,2395],{}," is common for package installation and service management",[20,2431,2432,2433,2435],{},"Modern Windows also has a native ",[37,2434,2395],{}," 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,2437,2439,2442,2445,2456],{"id":2438,"level":14},"quick-safety-routine",[16,2440,2441],{"id":2438},"Quick Safety Routine",[20,2443,2444],{},"Before a command changes files, ask:",[24,2446,2447,2450,2453],{},[27,2448,2449],{},"What folder am I in?",[27,2451,2452],{},"Do I see the files I expect?",[27,2454,2455],{},"Am I about to change the right folder?",[20,2457,2458,2459,2461,2462],{},"If one answer is unclear, stop and run ",[37,2460,90],{}," plus ",[37,2463,2464],{},"ls -la",[11,2466,2467,2469],{"id":977,"level":14},[16,2468,980],{"id":977},[24,2470,2471,2487,2493,2501],{},[27,2472,2473,2476,2477,2479,2480,2482,2483,2486],{},[37,2474,2475],{},"No such file or directory",": run ",[37,2478,90],{},", then ",[37,2481,1912],{},", then try ",[37,2484,2485],{},"cd"," again",[27,2488,2489,2490,2492],{},"Command affected the wrong folder: check ",[37,2491,90],{}," before continuing",[27,2494,2495,2497,2498,2500],{},[37,2496,2128],{}," cannot find the file: run ",[37,2499,2464],{}," and check the exact filename",[27,2502,2415],{},[11,2504,2506,2510],{"id":2505,"level":171},"common-mistakes-recovery",[173,2507,2509],{"id":2508},"recovery-checks","Recovery Checks",[24,2511,2512,2515,2520,2526],{},[27,2513,2514],{},"Spaces in a path: wrap the path in quotes",[27,2516,2517,2518],{},"Command keeps running: press ",[37,2519,791],{},[27,2521,2522,2523],{},"Permission denied: move back home with ",[37,2524,2525],{},"cd ~",[27,2527,2528,2529,2531],{},"Wrong ",[37,2530,2178],{},": stop and ask before doing more work",[11,2533,2534,2536,2539],{"id":875,"level":14},[16,2535,876],{"id":875},[20,2537,2538],{},"You are ready for the next setup lesson when these commands make sense:",[69,2540],{"language":71,"src":2541},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,2543,2545,2549],{"id":2544,"level":14},"further-learning",[16,2546,2548],{"id":2547},"key-terms-and-further-learning","Key Terms And Further Learning",[57,2550,2551,2581],{"gap":59,"left-width":60,"right-width":60},[62,2552,2553,2555,2561,2570],{"v-slot:left":64},[173,2554,1034],{"id":1031},[20,2556,2557,2560],{},[549,2558,2559],{},"Working directory"," - The folder where the next terminal command runs",[20,2562,2563,2566,2567],{},[549,2564,2565],{},"Path"," - A file or folder location, such as ",[37,2568,2569],{},"public_html\u002Findex.php",[20,2571,2572,2575,2576,2578,2579],{},[549,2573,2574],{},"Flag"," - An extra command option, such as ",[37,2577,2025],{}," in ",[37,2580,2464],{},[62,2582,2583,2586],{"v-slot:right":64},[173,2584,2585],{"id":2544},"Further Learning",[24,2587,2588,2595,2602],{},[27,2589,2590],{},[150,2591,2594],{"href":2592,"rel":2593},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[154],"Ubuntu Tutorial: The Linux Command Line For Beginners",[27,2596,2597],{},[150,2598,2601],{"href":2599,"rel":2600},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[154],"GNU Coreutils Manual",[27,2603,2604],{},[150,2605,2608],{"href":2606,"rel":2607},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[154],"MDN: Command Line Crash Course",[11,2610,2611,2613,2616],{"id":1057,"level":14},[16,2612,1060],{"id":1057},[20,2614,2615],{},"Before leaving this presentation, confirm you can:",[24,2617,2618,2623,2628,2639,2653],{},[27,2619,2245,2620,2622],{},[37,2621,90],{}," to check where commands will run",[27,2624,2245,2625,2627],{},[37,2626,2464],{}," to inspect the current folder",[27,2629,2245,2630,237,2632,237,2634,241,2636,2638],{},[37,2631,2485],{},[37,2633,128],{},[37,2635,1862],{},[37,2637,1888],{}," to move intentionally",[27,2640,2641,2642,237,2644,237,2646,237,2648,241,2650,2652],{},"Use file commands such as ",[37,2643,2160],{},[37,2645,2166],{},[37,2647,2172],{},[37,2649,2178],{},[37,2651,2289],{}," carefully",[27,2654,2655],{},"Stop and check location when output does not match the lesson",{"title":64,"searchDepth":1087,"depth":1087,"links":2657},[2658,2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2672,2673,2674,2675,2676,2678,2683,2684,2687,2688,2689],{"id":1649,"depth":1087,"text":1650},{"id":1704,"depth":1087,"text":1707},{"id":1739,"depth":1087,"text":1742},{"id":1774,"depth":1087,"text":1775},{"id":1832,"depth":1087,"text":1835},{"id":1898,"depth":1087,"text":1901},{"id":1951,"depth":1087,"text":1952},{"id":1974,"depth":1087,"text":1977},{"id":1991,"depth":1087,"text":1994},{"id":2029,"depth":1087,"text":2032},{"id":2060,"depth":1087,"text":2061},{"id":2081,"depth":1087,"text":2082,"children":2670},[2671],{"id":2116,"depth":1095,"text":2117},{"id":2138,"depth":1087,"text":2139},{"id":2210,"depth":1087,"text":2211},{"id":2233,"depth":1087,"text":2234},{"id":2278,"depth":1087,"text":2279},{"id":2338,"depth":1087,"text":2677},"Edit With nano",{"id":2390,"depth":1087,"text":2679,"children":2680},"sudo And Permission Boundaries",[2681],{"id":2418,"depth":1095,"text":2682},"sudo By Operating System",{"id":2438,"depth":1087,"text":2441},{"id":977,"depth":1087,"text":980,"children":2685},[2686],{"id":2508,"depth":1095,"text":2509},{"id":875,"depth":1087,"text":876},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"Practice the terminal commands you need so you can move through folders, inspect files, and verify your location before running course commands.","Face-to-face class of about 40 students; includes short CLI demo, student command practice, path\u002Fflag checks, and common beginner recovery questions.","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":1641,"description":2690},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[2698,2699,2700],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":2706,"title":2707,"audience":6,"body":2708,"contentType":1116,"course":1117,"description":3577,"estimateBasis":3578,"estimatedDiscussionMinutes":1621,"estimatedLiveMinutes":3579,"estimatedTotalMinutes":1121,"extension":1123,"meta":3580,"module":1125,"navigation":1126,"order":1622,"path":3581,"promptAssist":1128,"seo":3582,"status":1130,"stem":3583,"tags":3584,"videoDuration":3585,"videoId":3586,"videoLink":3587,"videoTitle":2707,"week":1125,"__hash__":3588},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":2709,"toc":3547},[2710,2733,2762,2790,2827,2858,2889,2923,2952,2982,3019,3022,3052,3083,3112,3162,3180,3197,3217,3242,3273,3291,3331,3376,3458,3518],[11,2711,2712,2714],{"id":1704,"level":14},[16,2713,1707],{"id":1704},[24,2715,2716,2719,2722],{},[27,2717,2718],{},"Install Git",[27,2720,2721],{},"Choose one terminal for your operating system",[27,2723,2724,2725,237,2728,241,2730,2732],{},"Confirm ",[37,2726,2727],{},"git --version",[37,2729,90],{},[37,2731,2464],{}," work before GitHub setup",[11,2734,2736,2740],{"id":2735,"level":14},"terminal-choice-by-os",[16,2737,2739],{"id":2738},"terminal-choices","Terminal Choices",[24,2741,2742,2745,2748,2751,2753,2756,2759],{},[27,2743,2744],{},"Pick the terminal for your operating system",[27,2746,2747],{},"Use that same terminal for this lesson path",[27,2749,2750],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[27,2752,1750],{},[27,2754,2755],{},"Apple macOS: Terminal, with iTerm2 optional",[27,2757,2758],{},"Linux: Terminal, with Tilix optional",[27,2760,2761],{},"These operating system notes are alternatives, not a sequence",[11,2763,2765,2769,2787],{"id":2764,"level":14},"step-1-install-git-on-windows",[16,2766,2768],{"id":2767},"windows-path-git-bash","Windows Path: Git Bash",[1282,2770,2771,2778,2781,2784],{},[27,2772,2773,2774],{},"Go to ",[150,2775,2776],{"href":2776,"rel":2777},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[154],[27,2779,2780],{},"Download and run the Git for Windows installer",[27,2782,2783],{},"Open Git Bash from the Start menu",[27,2785,2786],{},"Use Git Bash whenever this course says to use the terminal",[20,2788,2789],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,2791,2793,2796],{"id":2792,"level":171},"windows-installer-components",[173,2794,2795],{"id":2792},"Windows Installer: Components",[57,2797,2801,2809],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},"1.4fr","0.9fr","never",[62,2802,2803],{"v-slot:left":64},[20,2804,2805],{},[1263,2806],{"alt":2807,"src":2808,"variant":1267},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[62,2810,2811],{"v-slot:right":64},[24,2812,2813,2816,2821],{},[27,2814,2815],{},"Recommended to have these components selected",[27,2817,716,2818],{},[37,2819,2820],{},"Git Bash Here",[27,2822,2823,2824],{},"Continue with ",[37,2825,2826],{},"Next",[11,2828,2830,2833],{"id":2829,"level":171},"windows-installer-default-editor",[173,2831,2832],{"id":2829},"Windows Installer: Default Editor",[57,2834,2835,2843],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2836,2837],{"v-slot:left":64},[20,2838,2839],{},[1263,2840],{"alt":2841,"src":2842,"variant":1267},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[62,2844,2845],{"v-slot:right":64},[24,2846,2847,2850,2855],{},[27,2848,2849],{},"Choose the editor you are comfortable with",[27,2851,2852,2854],{},[37,2853,2289],{}," or VS Code is friendlier than Vim for most beginners",[27,2856,2857],{},"This setting affects Git messages if Git opens an editor",[11,2859,2861,2864],{"id":2860,"level":171},"windows-installer-branch-name",[173,2862,2863],{"id":2860},"Windows Installer: Branch Name",[57,2865,2866,2874],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2867,2868],{"v-slot:left":64},[20,2869,2870],{},[1263,2871],{"alt":2872,"src":2873,"variant":1267},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[62,2875,2876],{"v-slot:right":64},[24,2877,2878,2883,2886],{},[27,2879,2880,2881],{},"Select the option that uses ",[37,2882,45],{},[27,2884,2885],{},"Course repositories will tell you which branch to use later",[27,2887,2888],{},"Do not create custom branch names here",[11,2890,2892,2895],{"id":2891,"level":171},"windows-installer-path",[173,2893,2894],{"id":2891},"Windows Installer: PATH",[57,2896,2897,2905],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2898,2899],{"v-slot:left":64},[20,2900,2901],{},[1263,2902],{"alt":2903,"src":2904,"variant":1267},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[62,2906,2907],{"v-slot:right":64},[24,2908,2909,2912,2917,2920],{},[27,2910,2911],{},"Select the recommended PATH option",[27,2913,2914,2915],{},"This lets Git Bash and common tools find ",[37,2916,1134],{},[27,2918,2919],{},"Avoid options that say Git Bash only",[27,2921,2922],{},"The third option can be used if you understand the consequences",[11,2924,2926,2929],{"id":2925,"level":171},"windows-installer-ssh",[173,2927,2928],{"id":2925},"Windows Installer: SSH",[57,2930,2931,2939],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2932,2933],{"v-slot:left":64},[20,2934,2935],{},[1263,2936],{"alt":2937,"src":2938,"variant":1267},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[62,2940,2941],{"v-slot:right":64},[24,2942,2943,2946,2949],{},[27,2944,2945],{},"Use the bundled OpenSSH option",[27,2947,2948],{},"This keeps Git Bash SSH behavior predictable",[27,2950,2951],{},"SSH setup happens in the next lesson",[11,2953,2955,2959],{"id":2954,"level":171},"windows-installer-openssl",[173,2956,2958],{"id":2957},"windows-installer-https","Windows Installer: HTTPS",[57,2960,2961,2969],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2962,2963],{"v-slot:left":64},[20,2964,2965],{},[1263,2966],{"alt":2967,"src":2968,"variant":1267},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[62,2970,2971],{"v-slot:right":64},[24,2972,2973,2976,2979],{},[27,2974,2975],{},"Keep the OpenSSL option",[27,2977,2978],{},"This is the normal Git for Windows choice",[27,2980,2981],{},"It supports secure GitHub connections",[11,2983,2985,2989],{"id":2984,"level":171},"windows-installer-checkout-style",[173,2986,2988],{"id":2987},"windows-installer-line-endings","Windows Installer: Line Endings",[57,2990,2991,2999],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,2992,2993],{"v-slot:left":64},[20,2994,2995],{},[1263,2996],{"alt":2997,"src":2998,"variant":1267},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[62,3000,3001,3012],{"v-slot:right":64},[24,3002,3003,3006,3009],{},[27,3004,3005],{},"Keep the default line-ending option",[27,3007,3008],{},"Git handles Windows and Linux line endings for you",[27,3010,3011],{},"Do not change this unless a lesson says to",[3013,3014,3016],"admonition",{"type":3015},"note",[20,3017,3018],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[20,3020,3021],{},"::\n::",[11,3023,3025,3029],{"id":3024,"level":171},"windows-installer-mintty",[173,3026,3028],{"id":3027},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[57,3030,3031,3039],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,3032,3033],{"v-slot:left":64},[20,3034,3035],{},[1263,3036],{"alt":3037,"src":3038,"variant":1267},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[62,3040,3041],{"v-slot:right":64},[24,3042,3043,3046,3049],{},[27,3044,3045],{},"Keep MinTTY selected",[27,3047,3048],{},"This is the normal Git Bash window",[27,3050,3051],{},"Course screenshots will assume this terminal style",[11,3053,3055,3059],{"id":3054,"level":171},"windows-installer-fast-forward",[173,3056,3058],{"id":3057},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[57,3060,3061,3069],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,3062,3063],{"v-slot:left":64},[20,3064,3065],{},[1263,3066],{"alt":3067,"src":3068,"variant":1267},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[62,3070,3071],{"v-slot:right":64},[24,3072,3073,3080],{},[27,3074,3075,3076,3079],{},"Keep the default ",[37,3077,3078],{},"git pull"," behavior",[27,3081,3082],{},"Later lessons explain pull, merge, and conflicts",[11,3084,3086,3089],{"id":3085,"level":171},"windows-installer-credential-manager",[173,3087,3088],{"id":3085},"Windows Installer: Credential Manager",[57,3090,3091,3099],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,3092,3093],{"v-slot:left":64},[20,3094,3095],{},[1263,3096],{"alt":3097,"src":3098,"variant":1267},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[62,3100,3101],{"v-slot:right":64},[24,3102,3103,3106,3109],{},[27,3104,3105],{},"Keep Git Credential Manager enabled",[27,3107,3108],{},"It helps with browser-based GitHub sign-in",[27,3110,3111],{},"This course still uses SSH for repo pushes",[11,3113,3115,3118],{"id":3114,"level":171},"windows-installer-extra-options",[173,3116,3117],{"id":3114},"Windows Installer: Extra Options",[57,3119,3120,3128],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,3121,3122],{"v-slot:left":64},[20,3123,3124],{},[1263,3125],{"alt":3126,"src":3127,"variant":1267},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[62,3129,3130],{"v-slot:right":64},[24,3131,3132,3140,3151,3159],{},[27,3133,3134,3135],{},"Enable file system caching\n",[24,3136,3137],{},[27,3138,3139],{},"Improves Git performance on Windows",[27,3141,3142,3143],{},"Enable symbolic links if available\n",[24,3144,3145,3148],{},[27,3146,3147],{},"Helps Git handle link-like files correctly",[27,3149,3150],{},"May require Windows Developer Mode or admin rights",[27,3152,3153,3154],{},"Skip experimental options\n",[24,3155,3156],{},[27,3157,3158],{},"They can change behavior between Git versions",[27,3160,3161],{},"Finish the installer",[11,3163,3165,3169],{"id":3164,"level":171},"step-1-open-git-bash-on-windows",[173,3166,3168],{"id":3167},"open-git-bash","Open Git Bash",[24,3170,3171,3174,3177],{},[27,3172,3173],{},"Start menu -> Git Bash",[27,3175,3176],{},"Pin it if that helps you find the same terminal later",[27,3178,3179],{},"Run the checks in the next slides from Git Bash",[11,3181,3183,3186],{"id":3182,"level":171},"windows-terminal-habit",[173,3184,3185],{"id":3182},"Windows Terminal Habit",[24,3187,3188,3191,3194],{},[27,3189,3190],{},"Use Git Bash for course commands on Windows",[27,3192,3193],{},"If another terminal opens by accident, close it and open Git Bash",[27,3195,3196],{},"Staying in one terminal makes setup problems easier to diagnose",[11,3198,3200,3203],{"id":3199,"level":14},"macos-path-terminal",[16,3201,3202],{"id":3199},"macOS Path: Terminal",[24,3204,3205,3208,3211,3214],{},[27,3206,3207],{},"Built-in Terminal is fully supported",[27,3209,3210],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[27,3212,3213],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[27,3215,3216],{},"See the slide below for the optional modern terminal install path",[11,3218,3220,3224],{"id":3219,"level":171},"macos-optional-iterm2-install",[173,3221,3223],{"id":3222},"optional-iterm2-install","Optional iTerm2 Install",[24,3225,3226,3233,3236,3239],{},[27,3227,3228,3229],{},"Download the stable release from ",[150,3230,3231],{"href":3231,"rel":3232},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[154],[27,3234,3235],{},"Move iTerm2 to Applications",[27,3237,3238],{},"Open iTerm2 and run the same checks as Terminal",[27,3240,3241],{},"Use Terminal or iTerm2 consistently for course commands",[11,3243,3245,3248,3262,3265,3268],{"id":3244,"level":14},"linux-path-terminal",[16,3246,3247],{"id":3244},"Linux Path: Terminal",[24,3249,3250,3253,3256],{},[27,3251,3252],{},"Open the built-in Terminal app",[27,3254,3255],{},"Git is often installed already",[27,3257,3258,3259,3261],{},"If ",[37,3260,2727],{}," fails, use your distribution package manager",[20,3263,3264],{},"For Ubuntu:",[69,3266],{"language":71,"src":3267},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[24,3269,3270],{},[27,3271,3272],{},"See the slide below for the optional split-pane terminal setup",[11,3274,3276,3280,3283,3285,3288],{"id":3275,"level":171},"linux-optional-tilix-install",[173,3277,3279],{"id":3278},"optional-tilix-install","Optional Tilix Install",[20,3281,3282],{},"Tilix is a Linux terminal with split panes and profiles",[20,3284,3264],{},[69,3286],{"language":71,"src":3287},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[20,3289,3290],{},"Use the built-in Terminal if optional installs add friction",[11,3292,3294,3298],{"id":3293,"level":14},"step-3-confirm-git-and-shell",[16,3295,3297],{"id":3296},"confirm-git-and-shell","Confirm Git And Shell",[57,3299,3302,3315],{"gap":59,"left-width":3300,"right-width":3301},"1.15fr","0.85fr",[62,3303,3304,3306,3309,3312],{"v-slot:left":64},[20,3305,67],{},[69,3307],{"language":71,"src":3308},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[20,3310,3311],{},"Expected output:",[69,3313],{"language":81,"src":3314},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[62,3316,3317,3320],{"v-slot:right":64},[20,3318,3319],{},"This confirms:",[24,3321,3322,3325,3328],{},[27,3323,3324],{},"Git is installed",[27,3326,3327],{},"The terminal can find Git",[27,3329,3330],{},"Your shell matches later course commands",[11,3332,3334,3338],{"id":3333,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,3335,3337],{"id":3336},"check-location-before-git-commands","Check Location Before Git Commands",[57,3339,3341,3353],{"gap":59,"left-width":3340,"right-width":2799},"1.1fr",[62,3342,3343,3345,3348,3350],{"v-slot:left":64},[20,3344,67],{},[69,3346],{"language":71,"src":3347},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[20,3349,3311],{},[69,3351],{"language":81,"src":3352},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[62,3354,3355,3358],{"v-slot:right":64},[20,3356,3357],{},"Use this before Git commands:",[24,3359,3360,3365,3370,3373],{},[27,3361,3362,3364],{},[37,3363,90],{}," shows the current folder",[27,3366,3367,3369],{},[37,3368,2464],{}," shows what is inside it",[27,3371,3372],{},"If the folder is wrong, fix location first",[27,3374,3375],{},"Do not run Git commands while guessing",[11,3377,3378,3380],{"id":977,"level":14},[16,3379,980],{"id":977},[57,3381,3382,3424],{"gap":59,"left-width":60,"right-width":60},[62,3383,3384],{"v-slot:left":64},[24,3385,3386,3399,3416],{},[27,3387,3388,3391],{},[37,3389,3390],{},"git: command not found",[24,3392,3393,3396],{},[27,3394,3395],{},"Git is missing, or this terminal cannot find it",[27,3397,3398],{},"Close the terminal and reopen the correct one",[27,3400,3401,3404],{},[37,3402,3403],{},"not a git repository",[24,3405,3406,3409],{},[27,3407,3408],{},"The command ran outside a cloned repository",[27,3410,2245,3411,312,3413,3415],{},[37,3412,90],{},[37,3414,2464],{},", then move to the repo folder",[27,3417,3418,3419],{},"Wrong terminal",[24,3420,3421],{},[27,3422,3423],{},"Windows users should switch back to Git Bash",[62,3425,3426,3429],{"v-slot:right":64},[27,3427,3428],{},"Too many terminals open",[1282,3430,3431,3434,3444,3449,3455],{},[27,3432,3433],{},"Close extra terminal windows",[27,3435,3436,3437],{},"Open the correct terminal\n",[24,3438,3439,3441],{},[27,3440,1750],{},[27,3442,3443],{},"Apple macOS\u002FLinux: Terminal",[27,3445,3446,3447],{},"Run ",[37,3448,2727],{},[27,3450,3446,3451,312,3453],{},[37,3452,90],{},[37,3454,2464],{},[27,3456,3457],{},"Continue only after the folder looks right",[11,3459,3460,3462],{"id":2544,"level":14},[16,3461,2548],{"id":2547},[57,3463,3464,3486],{"gap":59,"left-width":60,"right-width":60},[62,3465,3466,3468,3474,3480],{"v-slot:left":64},[173,3467,1034],{"id":1031},[20,3469,3470,3473],{},[549,3471,3472],{},"Terminal"," - A text-based interface where you type commands to control your computer",[20,3475,3476,3479],{},[549,3477,3478],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[20,3481,3482,3485],{},[549,3483,3484],{},"Git"," - A tool for tracking changes in code files over time",[62,3487,3488,3490],{"v-slot:right":64},[173,3489,2585],{"id":2544},[24,3491,3492,3499,3505,3511],{},[27,3493,3494],{},[150,3495,3498],{"href":3496,"rel":3497},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[154],"Git Downloads",[27,3500,3501],{},[150,3502,3504],{"href":2776,"rel":3503},[154],"Git For Windows Install Page",[27,3506,3507],{},[150,3508,3510],{"href":3231,"rel":3509},[154],"iTerm2 Downloads",[27,3512,3513],{},[150,3514,3517],{"href":3515,"rel":3516},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[154],"Tilix",[11,3519,3520,3522,3525],{"id":1057,"level":14},[16,3521,1060],{"id":1057},[20,3523,3524],{},"Before moving on, confirm you can:",[24,3526,3527,3530,3534,3541,3544],{},[27,3528,3529],{},"Open the correct terminal for your operating system",[27,3531,3446,3532],{},[37,3533,2727],{},[27,3535,2245,3536,312,3538,3540],{},[37,3537,90],{},[37,3539,2464],{}," to check your location",[27,3542,3543],{},"Understand what terminal\u002FCLI refers to",[27,3545,3546],{},"Keep track of terminal instances",{"title":64,"searchDepth":1087,"depth":1087,"links":3548},[3549,3550,3551,3566,3569,3572,3573,3574,3575,3576],{"id":1704,"depth":1087,"text":1707},{"id":2738,"depth":1087,"text":2739},{"id":2767,"depth":1087,"text":2768,"children":3552},[3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,3564,3565],{"id":2792,"depth":1095,"text":2795},{"id":2829,"depth":1095,"text":2832},{"id":2860,"depth":1095,"text":2863},{"id":2891,"depth":1095,"text":2894},{"id":2925,"depth":1095,"text":2928},{"id":2957,"depth":1095,"text":2958},{"id":2987,"depth":1095,"text":2988},{"id":3027,"depth":1095,"text":3028},{"id":3057,"depth":1095,"text":3058},{"id":3085,"depth":1095,"text":3088},{"id":3114,"depth":1095,"text":3117},{"id":3167,"depth":1095,"text":3168},{"id":3182,"depth":1095,"text":3185},{"id":3199,"depth":1087,"text":3202,"children":3567},[3568],{"id":3222,"depth":1095,"text":3223},{"id":3244,"depth":1087,"text":3247,"children":3570},[3571],{"id":3278,"depth":1095,"text":3279},{"id":3296,"depth":1087,"text":3297},{"id":3336,"depth":1087,"text":3337},{"id":977,"depth":1087,"text":980},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"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":2707,"description":3577},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[1134,2699,1633],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":3590,"title":3591,"audience":6,"body":3592,"contentType":1116,"course":1117,"description":4662,"estimateBasis":4663,"estimatedDiscussionMinutes":1120,"estimatedLiveMinutes":4664,"estimatedTotalMinutes":4665,"extension":1123,"meta":4666,"module":1125,"navigation":1126,"order":1623,"path":4667,"promptAssist":1128,"seo":4668,"status":1130,"stem":4669,"tags":4670,"videoDuration":4673,"videoId":4674,"videoLink":4675,"videoTitle":4676,"week":1125,"__hash__":4677},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":3593,"toc":4634},[3594,3620,3638,3663,3676,3702,3739,3815,3862,3929,4005,4047,4073,4105,4142,4187,4221,4289,4291,4294,4305,4377,4406,4440,4488,4534,4602],[11,3595,3597,3600],{"id":3596,"level":14},"goals",[16,3598,3599],{"id":3596},"Goals",[24,3601,3602,3605,3608,3611,3614,3617],{},[27,3603,3604],{},"Confirm Git works in the correct terminal",[27,3606,3607],{},"Sign in to GitHub with a school or personal account",[27,3609,3610],{},"Create or reuse an SSH key for GitHub",[27,3612,3613],{},"Add the public key to GitHub",[27,3615,3616],{},"Create and clone your course repository",[27,3618,3619],{},"Set Git identity inside the cloned repository",[11,3621,3623,3626,3635],{"id":3622,"level":14},"terminal-by-os",[16,3624,3625],{"id":3622},"Terminal By OS",[24,3627,3628,3630,3633],{},[27,3629,1750],{},[27,3631,3632],{},"Apple macOS: Terminal or iTerm2",[27,3634,1765],{},[20,3636,3637],{},"Run these commands on your own computer",[11,3639,3641,3644],{"id":3640,"level":14},"git-and-ssh-terms",[16,3642,3643],{"id":3640},"Git And SSH Terms",[24,3645,3646,3649,3657,3660],{},[27,3647,3648],{},"Git identity: name and email attached to commits in a repository",[27,3650,3651,3652],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[24,3653,3654],{},[27,3655,3656],{},"This is how we'll authenticate to GitHub",[27,3658,3659],{},"SSH agent: helper that keeps your private key available to Git commands",[27,3661,3662],{},"Clone: local folder connected to a GitHub repository",[11,3664,3666,3669,3673],{"id":3665,"level":14},"ssh-key-flow",[16,3667,3668],{"id":3665},"SSH Key Flow",[3670,3671],"mermaid",{"code":3672},"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,3674,3675],{},"GitHub receives only the public key. The private key stays on your computer",[11,3677,3679,3682],{"id":3678,"level":14},"step-1-check-git",[16,3680,3681],{"id":3678},"Step 1: Check Git",[57,3683,3684,3692],{"gap":59,"left-width":60,"right-width":60},[62,3685,3686,3688],{"v-slot:left":64},[20,3687,67],{},[69,3689],{"label":3690,"language":71,"src":3691},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[62,3693,3694,3696,3699],{"v-slot:right":64},[20,3695,3311],{},[69,3697],{"label":83,"language":81,"src":3698},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[20,3700,3701],{},"A valid version means Git is installed and available in this terminal",[11,3703,3705,3709],{"id":3704,"level":14},"step-2-github-account",[16,3706,3708],{"id":3707},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[57,3710,3712,3731],{"gap":59,"left-width":60,"right-width":3711},"0.8fr",[62,3713,3714],{"v-slot:left":64},[24,3715,3716,3719,3722,3725,3728],{},[27,3717,3718],{},"Use an existing GitHub account or create one",[27,3720,3721],{},"School email recommended for course identity",[27,3723,3724],{},"Personal email is fine if you prefer it",[27,3726,3727],{},"Avoid work email so course access does not depend on an employer account",[27,3729,3730],{},"Confirm you can open GitHub Settings before continuing",[62,3732,3733],{"v-slot:right":64},[20,3734,3735],{},[1263,3736],{"alt":3737,"src":3738,"variant":1267},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3740,3742,3746],{"id":3741,"level":14},"step-2-create-repo",[16,3743,3745],{"id":3744},"step-3-create-course-repository","Step 3: Create Course Repository",[57,3747,3749,3807],{"gap":59,"left-width":3748,"right-width":3300},"0.95fr",[62,3750,3751,3753],{"v-slot:left":64},[20,3752,539],{},[24,3754,3755,3760,3766,3772,3787,3793,3796,3804],{},[27,3756,547,3757],{},[37,3758,3759],{},"+",[27,3761,3762,3763],{},"Choose ",[37,3764,3765],{},"New repository",[27,3767,3768,3769],{},"Name it ",[37,3770,3771],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[27,3773,3774,3775,3778,3779,3782,3783,3786],{},"Semester code examples: ",[37,3776,3777],{},"S2026"," spring, ",[37,3780,3781],{},"M2026"," summer, ",[37,3784,3785],{},"F2026"," fall",[27,3788,3789,3790],{},"Set visibility to ",[37,3791,3792],{},"Private",[27,3794,3795],{},"Toggle \"Add README\"",[27,3797,3798,3799],{},"Do not toggle \"Add .gitignore\"",[24,3800,3801],{},[27,3802,3803],{},"A future lesson will discuss and add this important file",[27,3805,3806],{},"Do not add starter files unless instructed",[62,3808,3809],{"v-slot:right":64},[20,3810,3811],{},[1263,3812],{"alt":3813,"src":3814,"variant":1267},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3816,3818,3822,3848],{"id":3817,"level":14},"step-3-check-existing-key",[16,3819,3821],{"id":3820},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[57,3823,3824,3832],{"gap":59,"left-width":60,"right-width":60},[62,3825,3826,3828],{"v-slot:left":64},[20,3827,67],{},[69,3829],{"label":3830,"language":71,"src":3831},"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",[62,3833,3834,3836,3839],{"v-slot:right":64},[20,3835,78],{},[69,3837],{"label":83,"language":81,"src":3838},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[20,3840,3841,3842,312,3845],{},"Look for a matching GitHub-specific pair such as ",[37,3843,3844],{},"github_key",[37,3846,3847],{},"github_key.pub",[20,3849,3850,3851,3854,3855,2296,3858,3861],{},"You can reuse an existing matching pair only if it is ",[549,3852,3853],{},"NOT"," a default key such as ",[37,3856,3857],{},"id_ed25519",[37,3859,3860],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3863,3865,3869,3871,3875,3877,3880],{"id":3864,"level":14},"step-4-create-key-if-needed",[16,3866,3868],{"id":3867},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[20,3870,67],{},[69,3872],{"label":3873,"language":71,"src":3874},"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,3876,78],{},[69,3878],{"label":83,"language":81,"src":3879},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[24,3881,3882,3908,3913,3918],{},[27,3883,3884,3885],{},"Command flags:\n",[24,3886,3887,3893,3899],{},[27,3888,3889,3892],{},[37,3890,3891],{},"-t"," chooses the key type",[27,3894,3895,3898],{},[37,3896,3897],{},"-C"," adds a comment label, usually your GitHub email",[27,3900,3901,3903,3904,3907],{},[37,3902,2260],{}," chooses the output file path (must include ",[37,3905,3906],{},"~\u002F.ssh\u002F"," followed by the file name)",[27,3909,3910,3912],{},[37,3911,3844],{}," is the private key file",[27,3914,3915,3917],{},[37,3916,3847],{}," is the public key file for GitHub",[27,3919,3920,3921],{},"Passphrase is optional unless your instructor requires one\n",[24,3922,3923,3926],{},[27,3924,3925],{},"Pro: protects the key if someone gets the file",[27,3927,3928],{},"Con: adds an unlock prompt when the key is used",[11,3930,3932,3936,3953,3985],{"id":3931,"level":14},"step-5-start-agent-and-add-key",[16,3933,3935],{"id":3934},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[57,3937,3938,3946],{"gap":59,"left-width":3340,"right-width":60},[62,3939,3940,3942],{"v-slot:left":64},[20,3941,67],{},[69,3943],{"label":3944,"language":71,"src":3945},"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",[62,3947,3948,3950],{"v-slot:right":64},[20,3949,78],{},[69,3951],{"label":83,"language":81,"src":3952},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[24,3954,3955,3961,3982],{},[27,3956,3957,3960],{},[37,3958,3959],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[27,3962,3963,3964,3967,3968,3971],{},"If that fails, run ",[37,3965,3966],{},"exec ssh-agent bash",", then run ",[37,3969,3970],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[24,3972,3973],{},[27,3974,2245,3975,3978,3979,3981],{},[37,3976,3977],{},"~\u002F.ssh\u002Fgithub_key"," because ",[37,3980,1888],{}," avoids issues with spaces in home directory paths",[27,3983,3984],{},"Then verify the key is loaded",[57,3986,3987,3995],{"gap":59,"left-width":60,"right-width":60},[62,3988,3989,3991],{"v-slot:left":64},[20,3990,67],{},[69,3992],{"label":3993,"language":71,"src":3994},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[62,3996,3997,3999,4002],{"v-slot:right":64},[20,3998,3311],{},[69,4000],{"label":83,"language":81,"src":4001},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[20,4003,4004],{},"One loaded key is enough for this lesson",[11,4006,4008,4012,4029],{"id":4007,"level":14},"step-6-copy-public-key",[16,4009,4011],{"id":4010},"step-7-copy-public-key","Step 7: Copy Public Key",[57,4013,4014,4022],{"gap":59,"left-width":60,"right-width":60},[62,4015,4016,4018],{"v-slot:left":64},[20,4017,67],{},[69,4019],{"label":4020,"language":71,"src":4021},"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",[62,4023,4024,4026],{"v-slot:right":64},[20,4025,78],{},[69,4027],{"label":83,"language":81,"src":4028},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[24,4030,4031,4041],{},[27,4032,4033,4034,4037,4038,4040],{},"Copy the full line starting with ",[37,4035,4036],{},"ssh-ed25519"," and ending with the value you set with ",[37,4039,3897],{}," earlier",[27,4042,4043,4044,4046],{},"Do not copy ",[37,4045,3844],{},", which is the private key (never share the private key)",[11,4048,4050,4054],{"id":4049,"level":14},"step-7-add-key-to-github",[16,4051,4053],{"id":4052},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[24,4055,4056,4059,4064,4067,4070],{},[27,4057,4058],{},"In GitHub, open account settings",[27,4060,2773,4061],{},[37,4062,4063],{},"SSH and GPG keys",[27,4065,4066],{},"Add a new authentication key",[27,4068,4069],{},"Paste the public key from the previous step",[27,4071,4072],{},"See the slides below for the GitHub screens",[11,4074,4076,4080],{"id":4075,"level":171},"step-8-open-github-settings",[173,4077,4079],{"id":4078},"open-github-settings","Open GitHub Settings",[57,4081,4082,4090],{"gap":59,"left-width":3340,"right-width":2799,"stack":2800},[62,4083,4084],{"v-slot:left":64},[20,4085,4086],{},[1263,4087],{"alt":4088,"src":4089,"variant":1267},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[62,4091,4092],{"v-slot:right":64},[24,4093,4094,4097,4102],{},[27,4095,4096],{},"Click your GitHub profile photo",[27,4098,3762,4099],{},[37,4100,4101],{},"Settings",[27,4103,4104],{},"Use the account menu, not the repository settings",[11,4106,4108,4112],{"id":4107,"level":171},"step-8-open-ssh-keys-page",[173,4109,4111],{"id":4110},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[57,4113,4114,4122],{"gap":59,"left-width":3340,"right-width":2799,"stack":2800},[62,4115,4116],{"v-slot:left":64},[20,4117,4118],{},[1263,4119],{"alt":4120,"src":4121,"variant":1267},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[62,4123,4124],{"v-slot:right":64},[24,4125,4126,4133,4137],{},[27,4127,4128,4129,4132],{},"Find the ",[37,4130,4131],{},"Access"," section",[27,4134,840,4135],{},[37,4136,4063],{},[27,4138,3762,4139],{},[37,4140,4141],{},"New SSH key",[11,4143,4145,4149],{"id":4144,"level":171},"step-8-add-new-ssh-key",[173,4146,4148],{"id":4147},"add-new-ssh-key","Add New SSH Key",[57,4150,4152,4160],{"gap":59,"left-width":4151,"right-width":3301,"stack":2800},"1.35fr",[62,4153,4154],{"v-slot:left":64},[20,4155,4156],{},[1263,4157],{"alt":4158,"src":4159,"variant":1267},"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",[62,4161,4162],{"v-slot:right":64},[24,4163,4164,4170,4176,4179,4184],{},[27,4165,4166,4167],{},"Title it clearly, such as ",[37,4168,4169],{},"\u003Ccourse> Laptop",[27,4171,4172,4173],{},"Keep key type as ",[37,4174,4175],{},"Authentication Key",[27,4177,4178],{},"Paste the full public key line",[27,4180,547,4181],{},[37,4182,4183],{},"Add SSH key",[27,4185,4186],{},"Never paste the private key",[11,4188,4190,4194],{"id":4189,"level":14},"step-8-test-auth",[16,4191,4193],{"id":4192},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[57,4195,4196,4211],{"gap":59,"left-width":60,"right-width":3340},[62,4197,4198,4200,4204],{"v-slot:left":64},[20,4199,67],{},[69,4201],{"label":4202,"language":71,"src":4203},"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,4205,4206,4207,4210],{},"If prompted the first time, type ",[37,4208,4209],{},"yes"," to trust GitHub's host key",[62,4212,4213,4215,4218],{"v-slot:right":64},[20,4214,3311],{},[69,4216],{"label":83,"language":81,"src":4217},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[20,4219,4220],{},"This confirms authentication, then GitHub closes the connection",[11,4222,4224,4228],{"id":4223,"level":14},"step-9-clone-repo",[16,4225,4227],{"id":4226},"step-10-clone-course-repository","Step 10: Clone Course Repository",[57,4229,4230,4271],{"gap":59,"left-width":2799,"right-width":3340},[62,4231,4232,4236,4265],{"v-slot:left":64},[173,4233,4235],{"id":4234},"get-the-ssh-clone-url","Get The SSH Clone URL",[24,4237,4238,4244,4251,4258],{},[27,4239,4240,4241],{},"In your GitHub repository, click ",[37,4242,4243],{},"Code",[27,4245,4246,4247,4250],{},"Choose the ",[37,4248,4249],{},"SSH"," tab",[27,4252,4253,4254,4257],{},"Copy the ",[37,4255,4256],{},"git@github.com:..."," link",[27,4259,4260,4261,4264],{},"Use that link in the ",[37,4262,4263],{},"git clone"," command",[20,4266,4267],{},[1263,4268],{"alt":4269,"src":4270,"variant":1267},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[62,4272,4273,4276,4280],{"v-slot:right":64},[20,4274,4275],{},"Run from the folder that should contain your course repo:",[69,4277],{"label":4278,"language":71,"src":4279},"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",[3013,4281,4283],{"type":4282},"tip",[20,4284,4285,4286,4288],{},"Before cloning, run ",[37,4287,962],{},". If it prints a path, move somewhere else first. Clone this repo only once.",[20,4290,78],{},[69,4292],{"label":83,"language":81,"src":4293},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[20,4295,4296,4297,4300,4301,4304],{},"If you see an empty repository warning, you probably forgot to add ",[37,4298,4299],{},"README.md"," when creating the repo. Create it with ",[37,4302,4303],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,4306,4308,4312,4331,4350,4370],{"id":4307,"level":14},"step-10-set-repo-identity",[16,4309,4311],{"id":4310},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[57,4313,4314,4323],{"gap":59,"left-width":60,"right-width":60},[62,4315,4316,4319],{"v-slot:left":64},[20,4317,4318],{},"Run inside the cloned repository:",[69,4320],{"label":4321,"language":71,"src":4322},"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",[62,4324,4325,4327],{"v-slot:right":64},[20,4326,3311],{},[69,4328],{"label":4329,"language":81,"src":4330},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[57,4332,4333,4342],{"gap":59,"left-width":60,"right-width":60},[62,4334,4335,4338],{"v-slot:left":64},[20,4336,4337],{},"Then verify:",[69,4339],{"label":4340,"language":71,"src":4341},"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",[62,4343,4344,4346],{"v-slot:right":64},[20,4345,3311],{},[69,4347],{"label":4348,"language":81,"src":4349},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[24,4351,4352,4358,4364],{},[27,4353,4354,4357],{},[37,4355,4356],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[27,4359,4360,4363],{},[37,4361,4362],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[27,4365,4366,4369],{},[37,4367,4368],{},"core.sshCommand"," tells this repository to use your course GitHub key",[20,4371,4372,4373,4376],{},"These commands set identity for this repository. The ",[37,4374,4375],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,4378,4380,4384,4387,4403],{"id":4379,"level":14},"step-11-invite-collaborators",[16,4381,4383],{"id":4382},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[20,4385,4386],{},"In GitHub, open your course repository:",[24,4388,4389,4392,4397,4400],{},[27,4390,4391],{},"Settings -> Collaborators and teams",[27,4393,4394,4395],{},"Invite ",[37,4396,1495],{},[27,4398,4399],{},"Invite your TA if your section has one",[27,4401,4402],{},"Wait until the invitation shows as sent or accepted",[20,4404,4405],{},"This is so it can be accessed for grading and assistance",[11,4407,4409,4412],{"id":4408,"level":14},"troubleshooting-auth",[16,4410,4411],{"id":4408},"Troubleshooting Auth",[24,4413,4414,4420,4427,4434,4437],{},[27,4415,4416,4419],{},[37,4417,4418],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[27,4421,4422,4423,4426],{},"No loaded key in ",[37,4424,4425],{},"ssh-add -l",": start the agent and add the key again",[27,4428,4429,4430,4433],{},"Wrong key in GitHub: delete it and paste the ",[37,4431,4432],{},".pub"," key again",[27,4435,4436],{},"Wrong account: make sure the success message names your GitHub account",[27,4438,4439],{},"See the slide below for a quick reset sequence",[11,4441,4443,4447,4449,4476],{"id":4442,"level":171},"troubleshooting-auth-recovery",[173,4444,4446],{"id":4445},"quick-reset-sequence","Quick Reset Sequence",[20,4448,67],{},[1282,4450,4451,4455,4459,4463,4468,4471],{},[27,4452,4453],{},[37,4454,3959],{},[27,4456,4457],{},[37,4458,3970],{},[27,4460,4461],{},[37,4462,4425],{},[27,4464,4465],{},[37,4466,4467],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[27,4469,4470],{},"Re-paste the public key in GitHub if needed",[27,4472,4473],{},[37,4474,4475],{},"ssh -T git@github.com",[20,4477,3258,4478,4480,4481,4483,4484,4487],{},[37,4479,3959],{}," fails in Git Bash, use ",[37,4482,3966],{},", then repeat the ",[37,4485,4486],{},"ssh-add"," steps",[11,4489,4490,4492,4495],{"id":875,"level":14},[16,4491,876],{"id":875},[20,4493,4494],{},"You are done when all are true:",[24,4496,4497,4502,4509,4514,4517,4522,4525],{},[27,4498,4499,4501],{},[37,4500,2727],{}," works",[27,4503,4504,4506,4507],{},[37,4505,4425],{}," shows ",[37,4508,3844],{},[27,4510,4511,4513],{},[37,4512,4475],{}," names your GitHub account",[27,4515,4516],{},"Your private course repository exists on GitHub",[27,4518,4519,4521],{},[37,4520,1495],{}," and your TA, if applicable, are invited as collaborators",[27,4523,4524],{},"Your local terminal is open to the cloned repository",[27,4526,4527,312,4530,4533],{},[37,4528,4529],{},"git config user.name",[37,4531,4532],{},"git config user.email"," return your repo identity",[11,4535,4536,4538],{"id":2544,"level":14},[16,4537,2548],{"id":2547},[57,4539,4540,4568],{"gap":59,"left-width":60,"right-width":60},[62,4541,4542,4544,4550,4556,4562],{"v-slot:left":64},[173,4543,1034],{"id":1031},[20,4545,4546,4549],{},[549,4547,4548],{},"Git identity"," - commit name and email saved in repo config",[20,4551,4552,4555],{},[549,4553,4554],{},"SSH key pair"," - private key on your computer, public key in GitHub",[20,4557,4558,4561],{},[549,4559,4560],{},"SSH agent"," - background helper that makes your private key available",[20,4563,4564,4567],{},[549,4565,4566],{},"Clone"," - local copy of a GitHub repository",[62,4569,4570,4572],{"v-slot:right":64},[173,4571,2585],{"id":2544},[24,4573,4574,4581,4588,4595],{},[27,4575,4576],{},[150,4577,4580],{"href":4578,"rel":4579},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[154],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[27,4582,4583],{},[150,4584,4587],{"href":4585,"rel":4586},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[154],"GitHub Docs: Testing your SSH connection",[27,4589,4590],{},[150,4591,4594],{"href":4592,"rel":4593},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[154],"GitHub Docs: Create a repository",[27,4596,4597],{},[150,4598,4601],{"href":4599,"rel":4600},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[154],"GitHub Docs: Cloning a repository",[11,4603,4604,4606,4608],{"id":1057,"level":14},[16,4605,1060],{"id":1057},[20,4607,2615],{},[24,4609,4610,4613,4616,4619,4622,4625,4631],{},[27,4611,4612],{},"Use the correct terminal for your operating system",[27,4614,4615],{},"Authenticate to GitHub with SSH",[27,4617,4618],{},"Find your private course repository on GitHub",[27,4620,4621],{},"Invite course collaborators",[27,4623,4624],{},"Open the local clone in the terminal",[27,4626,4627,4628],{},"Show repo-local Git identity with ",[37,4629,4630],{},"git config",[27,4632,4633],{},"Next: practice the Git commands used for course work",{"title":64,"searchDepth":1087,"depth":1087,"links":4635},[4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4652,4653,4654,4655,4656,4659,4660,4661],{"id":3596,"depth":1087,"text":3599},{"id":3622,"depth":1087,"text":3625},{"id":3640,"depth":1087,"text":3643},{"id":3665,"depth":1087,"text":3668},{"id":3678,"depth":1087,"text":3681},{"id":3707,"depth":1087,"text":3708},{"id":3744,"depth":1087,"text":3745},{"id":3820,"depth":1087,"text":3821},{"id":3867,"depth":1087,"text":3868},{"id":3934,"depth":1087,"text":3935},{"id":4010,"depth":1087,"text":4011},{"id":4052,"depth":1087,"text":4053,"children":4648},[4649,4650,4651],{"id":4078,"depth":1095,"text":4079},{"id":4110,"depth":1095,"text":4111},{"id":4147,"depth":1095,"text":4148},{"id":4192,"depth":1087,"text":4193},{"id":4226,"depth":1087,"text":4227},{"id":4310,"depth":1087,"text":4311},{"id":4382,"depth":1087,"text":4383},{"id":4408,"depth":1087,"text":4411,"children":4657},[4658],{"id":4445,"depth":1095,"text":4446},{"id":875,"depth":1087,"text":876},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"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.","70","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":3591,"description":4662},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[1134,4671,4672,1133],"github","ssh","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":4679,"title":4680,"audience":6,"body":4681,"contentType":1116,"course":1117,"description":5592,"estimateBasis":5593,"estimatedDiscussionMinutes":1622,"estimatedLiveMinutes":4664,"estimatedTotalMinutes":5594,"extension":1123,"meta":5595,"module":1125,"navigation":1126,"order":5596,"path":5597,"promptAssist":1128,"seo":5598,"status":1130,"stem":5599,"tags":5600,"videoDuration":5603,"videoId":5604,"videoLink":5605,"videoTitle":5606,"week":1125,"__hash__":5607},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":4682,"toc":5557},[4683,4710,4731,4747,4779,4813,4864,4880,4901,4931,4963,5005,5035,5070,5093,5138,5164,5194,5212,5224,5260,5293,5329,5363,5388,5415,5445,5512,5554],[11,4684,4685,4687,4690],{"id":13,"level":14},[16,4686,18],{"id":13},[20,4688,4689],{},"By the end, you should be able to:",[24,4691,4692,4695,4698,4701,4704,4707],{},[27,4693,4694],{},"Explain what the common Git commands do",[27,4696,4697],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[27,4699,4700],{},"Create a branch for practice work",[27,4702,4703],{},"Stage, commit, and push a small change",[27,4705,4706],{},"Open a pull request on GitHub",[27,4708,4709],{},"Investigate a failed push and a merge conflict",[11,4711,4713,4717,4720,4723],{"id":4712,"level":14},"git-vs-github",[16,4714,4716],{"id":4715},"git-versus-github","Git Versus GitHub",[20,4718,4719],{},"Git is the tool that tracks file history",[20,4721,4722],{},"GitHub is a website that hosts a remote copy of a Git repository",[24,4724,4725,4728],{},[27,4726,4727],{},"Git: local terminal workflow",[27,4729,4730],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,4732,4734,4738,4741,4744],{"id":4733,"level":14},"git-stages",[16,4735,4737],{"id":4736},"the-git-stages","The Git Stages",[69,4739],{"language":213,"src":4740},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[20,4742,4743],{},"Common commands:",[69,4745],{"language":213,"src":4746},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,4748,4750,4754,4756,4759,4762,4765],{"id":4749,"level":14},"status-first",[16,4751,4753],{"id":4752},"command-1-git-status","Command 1: git status",[20,4755,67],{},[69,4757],{"language":71,"src":4758},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[20,4760,4761],{},"Use this before and after every important Git action",[20,4763,4764],{},"It tells you:",[24,4766,4767,4770,4773,4776],{},[27,4768,4769],{},"Current branch",[27,4771,4772],{},"Changed files",[27,4774,4775],{},"Staged files",[27,4777,4778],{},"Whether your working tree is clean",[11,4780,4782,4786,4788,4791],{"id":4781,"level":14},"branch-command",[16,4783,4785],{"id":4784},"command-2-git-branch","Command 2: git branch",[20,4787,67],{},[69,4789],{"language":71,"src":4790},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[24,4792,4793,4796,4799],{},[27,4794,4795],{},"Active branch has an asterisk",[27,4797,4798],{},"Branches are separate timelines for work",[27,4800,4801,4802],{},"Branch names are case-sensitive\n",[24,4803,4804],{},[27,4805,4806,312,4809,4812],{},[37,4807,4808],{},"Practice",[37,4810,4811],{},"practice"," are different names",[11,4814,4816,4820,4825,4828],{"id":4815,"level":14},"create-branch",[16,4817,4819],{"id":4818},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[20,4821,4822,4823,2353],{},"Start from ",[37,4824,45],{},[69,4826],{"language":71,"src":4827},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[24,4829,4830,4841],{},[27,4831,4832,4833,4835,4836],{},"First two commands: make sure ",[37,4834,45],{}," is current\n",[24,4837,4838],{},[27,4839,4840],{},"Explained more later",[27,4842,4843,4844],{},"Branch control commands\n",[24,4845,4846,4852,4858],{},[27,4847,4848,4851],{},[37,4849,4850],{},"git checkout -b practice",": create and switch",[27,4853,4854,4857],{},[37,4855,4856],{},"git branch practice",": create only",[27,4859,4860,4863],{},[37,4861,4862],{},"git checkout practice",": switch to existing",[11,4865,4867,4871,4874,4877],{"id":4866,"level":14},"make-file",[16,4868,4870],{"id":4869},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[20,4872,4873],{},"Create a small practice file:",[69,4875],{"language":71,"src":4876},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[20,4878,4879],{},"Expected result: Git shows the new file as untracked",[11,4881,4883,4887,4890,4893,4896],{"id":4882,"level":14},"add-command",[16,4884,4886],{"id":4885},"command-3-git-add","Command 3: git add",[20,4888,4889],{},"Stage the new file:",[69,4891],{"language":71,"src":4892},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[20,4894,4895],{},"Staging means: include this change in the next commit",[24,4897,4898],{},[27,4899,4900],{},"See below for add patterns and verification checks",[11,4902,4904,4908,4911,4914],{"id":4903,"level":171},"add-variants",[173,4905,4907],{"id":4906},"common-git-add-patterns","Common git add Patterns",[20,4909,4910],{},"Use the smallest clear target when possible",[69,4912],{"language":71,"src":4913},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[24,4915,4916,4919,4922],{},[27,4917,4918],{},"Single file: safest when you changed one file",[27,4920,4921],{},"Folder: useful when one feature is grouped in one folder",[27,4923,4924,4927,4928,4930],{},[37,4925,4926],{},"git add .",": convenient, but review ",[37,4929,96],{}," first",[11,4932,4934,4938,4941,4944],{"id":4933,"level":14},"diff-command",[16,4935,4937],{"id":4936},"command-4-git-diff","Command 4: git diff",[20,4939,4940],{},"Before committing, inspect what changed:",[69,4942],{"language":71,"src":4943},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[24,4945,4946,4953,4956,4961],{},[27,4947,4948,4949,4952],{},"New untracked file: ",[37,4950,4951],{},"git diff"," may show nothing",[27,4954,4955],{},"That does not mean the file is missing",[27,4957,2245,4958,4960],{},[37,4959,96],{}," to confirm untracked files",[27,4962,2415],{},[11,4964,4966,4970,4973,4976,4979,4982],{"id":4965,"level":171},"cached-rm",[173,4967,4969],{"id":4968},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[20,4971,4972],{},"If a file was staged by mistake, remove it from staging:",[69,4974],{"language":71,"src":4975},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[20,4977,4978],{},"For a folder:",[69,4980],{"language":71,"src":4981},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[24,4983,4984,4995],{},[27,4985,4986,4989,4990],{},[37,4987,4988],{},"--cached",": remove from staging only\n",[24,4991,4992],{},[27,4993,4994],{},"Keeps the file in your working folder",[27,4996,4997,4999,5000],{},[37,4998,1727],{},": folder mode\n",[24,5001,5002],{},[27,5003,5004],{},"Recursive: include files inside the folder",[11,5006,5008,5012,5015,5018,5021],{"id":5007,"level":14},"commit-command",[16,5009,5011],{"id":5010},"command-5-git-commit","Command 5: git commit",[20,5013,5014],{},"Commit the staged file:",[69,5016],{"language":71,"src":5017},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[20,5019,5020],{},"A commit is a saved checkpoint in your local repository",[24,5022,5023,5033],{},[27,5024,5025,5027,5028],{},[37,5026,470],{},": commit message",[24,5029,5030],{},[27,5031,5032],{},"Required, even if the message is an empty string",[27,5034,2415],{},[11,5036,5038,5042,5044,5047,5067],{"id":5037,"level":171},"log-command",[173,5039,5041],{"id":5040},"check-the-local-history","Check The Local History",[20,5043,67],{},[69,5045],{"language":71,"src":5046},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[24,5048,5049,5055,5061],{},[27,5050,5051,5054],{},[37,5052,5053],{},"log",": show commit history",[27,5056,5057,5060],{},[37,5058,5059],{},"--oneline",": one commit per line",[27,5062,5063,5066],{},[37,5064,5065],{},"-5",": show the latest five commits",[20,5068,5069],{},"You should see your latest commit near the top",[11,5071,5073,5077,5080,5083],{"id":5072,"level":14},"push-command",[16,5074,5076],{"id":5075},"command-6-git-push","Command 6: git push",[20,5078,5079],{},"Send the branch to GitHub:",[69,5081],{"language":71,"src":5082},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[24,5084,5085,5090],{},[27,5086,5087,5089],{},[37,5088,510],{},": common remote name for GitHub",[27,5091,5092],{},"Final part: branch you are pushing",[11,5094,5096,5100],{"id":5095,"level":14},"open-pr",[16,5097,5099],{"id":5098},"pull-request","Pull Request",[57,5101,5102,5130],{"gap":59,"left-width":60,"right-width":60},[62,5103,5104,5107,5110,5113,5116,5119],{"v-slot:left":64},[20,5105,5106],{},"On GitHub, open a pull request",[20,5108,5109],{},"Use this direction:",[69,5111],{"language":213,"src":5112},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[20,5114,5115],{},"Use a clear description:",[69,5117],{"language":213,"src":5118},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[24,5120,5121,5124,5127],{},[27,5122,5123],{},"Review page before merge",[27,5125,5126],{},"Shows what will change",[27,5128,5129],{},"Captures branch evidence",[62,5131,5132],{"v-slot:right":64},[20,5133,5134],{},[1263,5135],{"alt":5136,"src":5137,"variant":1267},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,5139,5141,5145,5148,5155,5158,5161],{"id":5140,"level":14},"merge-pr",[16,5142,5144],{"id":5143},"merge-and-sync","Merge And Sync",[20,5146,5147],{},"After GitHub merge:",[24,5149,5150],{},[27,5151,898,5152,5154],{},[37,5153,45],{}," is not updated automatically",[20,5156,5157],{},"Sync it:",[69,5159],{"language":71,"src":5160},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[20,5162,5163],{},"Remote changes must be pulled down intentionally",[11,5165,5167,5171,5174,5191],{"id":5166,"level":14},"why-prs",[16,5168,5170],{"id":5169},"why-pull-requests-matter","Why Pull Requests Matter",[20,5172,5173],{},"Pull requests create evidence:",[24,5175,5176,5179,5182,5185,5188],{},[27,5177,5178],{},"Which branch changed",[27,5180,5181],{},"Which files changed",[27,5183,5184],{},"What discussion or explanation was provided",[27,5186,5187],{},"Chance to review risky changes before merging",[27,5189,5190],{},"When the change was merged",[20,5192,5193],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,5195,5197,5201,5204],{"id":5196,"level":14},"exploration-intro",[16,5198,5200],{"id":5199},"troubleshooting-explorations","Troubleshooting Explorations",[20,5202,5203],{},"The next slides use controlled problems to practice recovery",[24,5205,5206,5209],{},[27,5207,5208],{},"The goal is not avoiding every error",[27,5210,5211],{},"The goal is reading output, identifying state, and recovering without guessing",[11,5213,5215,5218,5221],{"id":5214,"level":14},"exploration-setup",[16,5216,5217],{"id":5214},"Exploration Setup",[20,5219,5220],{},"Create a conflict practice branch:",[69,5222],{"language":71,"src":5223},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,5225,5227,5231,5237,5244,5249,5252,5255],{"id":5226,"level":14},"exploration-issue-1",[16,5228,5230],{"id":5229},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[20,5232,5233,5234],{},"On GitHub, switch to ",[37,5235,5236],{},"practice-conflict",[20,5238,5239,5240,5243],{},"Edit one line in ",[37,5241,5242],{},"myFile.txt"," directly on GitHub and commit the change",[24,5245,5246],{},[27,5247,5248],{},"Use the same line you will change locally",[20,5250,5251],{},"Back locally, edit that same line and commit:",[69,5253],{"language":71,"src":5254},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[24,5256,5257],{},[27,5258,5259],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,5261,5263,5267,5270],{"id":5262,"level":171},"issue-1-push-without-pulling",[173,5264,5266],{"id":5265},"try-push-without-pulling","Try Push Without Pulling",[20,5268,5269],{},"Push the local commit before pulling the GitHub commit:",[57,5271,5272,5285],{"gap":59,"left-width":60,"right-width":60},[62,5273,5274,5277],{"v-slot:left":64},[69,5275],{"language":71,"src":5276},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[24,5278,5279,5282],{},[27,5280,5281],{},"Expected result: push rejected",[27,5283,5284],{},"Reason: GitHub has a commit your local branch does not have",[62,5286,5287],{"v-slot:right":64},[20,5288,5289],{},[1263,5290],{"alt":5291,"src":5292,"variant":1267},"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,5294,5296,5300],{"id":5295,"level":171},"issue-1-read-output",[173,5297,5299],{"id":5298},"pull-the-remote-change","Pull The Remote Change",[57,5301,5302,5321],{"gap":59,"left-width":60,"right-width":60},[62,5303,5304,5307,5310,5313,5318],{"v-slot:left":64},[20,5305,5306],{},"The usual next command is:",[69,5308],{"language":71,"src":5309},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[20,5311,5312],{},"If Git asks how to reconcile divergent branches:",[24,5314,5315],{},[27,5316,5317],{},"Use merge behavior for this course practice",[69,5319],{"language":71,"src":5320},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[62,5322,5323],{"v-slot:right":64},[20,5324,5325],{},[1263,5326],{"alt":5327,"src":5328,"variant":1267},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,5330,5332,5336,5339,5343,5346,5349,5352],{"id":5331,"level":14},"exploration-issue-2",[16,5333,5335],{"id":5334},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[20,5337,5338],{},"After pulling, Git should report a conflict",[20,5340,840,5341],{},[37,5342,5242],{},[20,5344,5345],{},"You may see markers like:",[69,5347],{"language":213,"src":5348},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[20,5350,5351],{},"Conflict markers show:",[24,5353,5354,5357,5360],{},[27,5355,5356],{},"Your local version",[27,5358,5359],{},"The GitHub version",[27,5361,5362],{},"The part Git could not combine automatically",[11,5364,5366,5370,5376,5379,5381,5384],{"id":5365,"level":171},"resolve-conflict",[173,5367,5369],{"id":5368},"resolve-the-conflict","Resolve The Conflict",[20,5371,5372,5373,5375],{},"Edit ",[37,5374,5242],{}," so it contains the final text you want",[20,5377,5378],{},"Remove all conflict markers",[20,5380,631],{},[69,5382],{"language":71,"src":5383},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[24,5385,5386],{},[27,5387,2415],{},[11,5389,5391,5395,5398],{"id":5390,"level":171},"verify-conflict-resolution",[173,5392,5394],{"id":5393},"verify-the-recovery","Verify The Recovery",[20,5396,5397],{},"Check:",[24,5399,5400,5404,5407,5412],{},[27,5401,5402,662],{},[37,5403,96],{},[27,5405,5406],{},"GitHub shows the updated branch",[27,5408,5409,5411],{},[37,5410,5242],{}," contains the final text",[27,5413,5414],{},"No conflict markers remain",[11,5416,5417,5419],{"id":977,"level":14},[16,5418,980],{"id":977},[24,5420,5421,5424,5427,5430,5433,5442],{},[27,5422,5423],{},"Committing on the wrong branch",[27,5425,5426],{},"Forgetting to push after committing",[27,5428,5429],{},"Forgetting to pull after merging on GitHub",[27,5431,5432],{},"Leaving conflict markers in a file",[27,5434,5435,5436,2296,5439],{},"Using vague branch names like ",[37,5437,5438],{},"stuff",[37,5440,5441],{},"final",[27,5443,5444],{},"Making several unrelated changes in one commit",[11,5446,5447,5449],{"id":2544,"level":14},[16,5448,2548],{"id":2547},[57,5450,5451,5475],{"gap":59,"left-width":60,"right-width":60},[62,5452,5453,5455],{"v-slot:left":64},[173,5454,1034],{"id":1031},[24,5456,5457,5460,5463,5466,5469,5472],{},[27,5458,5459],{},"Working folder: files you can edit",[27,5461,5462],{},"Staging area: changes selected for the next commit",[27,5464,5465],{},"Commit: local saved checkpoint",[27,5467,5468],{},"Remote: GitHub copy of the repository",[27,5470,5471],{},"Pull request: GitHub page for reviewing and merging branch work",[27,5473,5474],{},"Conflict: a change Git cannot merge automatically",[62,5476,5477,5479],{"v-slot:right":64},[173,5478,2585],{"id":2544},[24,5480,5481,5489,5496,5504],{},[27,5482,5483,5484],{},"Pro Git Book: ",[150,5485,5488],{"href":5486,"rel":5487},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[154],"Git Basics",[27,5490,5483,5491],{},[150,5492,5495],{"href":5493,"rel":5494},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[154],"Basic Branching and Merging",[27,5497,5498,5499],{},"GitHub Docs: ",[150,5500,5503],{"href":5501,"rel":5502},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[154],"Creating a pull request",[27,5505,5506,5507],{},"Oh Shit, Git!?!: ",[150,5508,5511],{"href":5509,"rel":5510},"https:\u002F\u002Fohshitgit.com\u002F",[154],"Common Git recovery situations",[11,5513,5514,5516],{"id":1057,"level":14},[16,5515,1060],{"id":1057},[57,5517,5520,5544],{"gap":1123,"left-width":5518,"right-width":5519},"0.72fr","1.38fr",[62,5521,5522,5524],{"v-slot:left":64},[20,5523,2615],{},[24,5525,5526,5532,5535,5538,5541],{},[27,5527,5528,5529,5531],{},"Read ",[37,5530,96],{}," before choosing the next command",[27,5533,5534],{},"Move a change from working folder to staging area to commit",[27,5536,5537],{},"Push a branch to GitHub and open a pull request",[27,5539,5540],{},"Recognize when a failed push or conflict needs recovery",[27,5542,5543],{},"Next: open the cloned repository in VS Code",[62,5545,5546,5549],{"v-slot:right":64},[20,5547,5548],{},"Git\u002FGitHub flow:",[5550,5551],"figure-image",{"alt":5552,"src":5553},"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,5555,5556],{},"::",{"title":64,"searchDepth":1087,"depth":1087,"links":5558},[5559,5560,5561,5562,5563,5564,5565,5566,5569,5572,5575,5576,5577,5578,5579,5580,5581,5585,5589,5590,5591],{"id":13,"depth":1087,"text":18},{"id":4715,"depth":1087,"text":4716},{"id":4736,"depth":1087,"text":4737},{"id":4752,"depth":1087,"text":4753},{"id":4784,"depth":1087,"text":4785},{"id":4818,"depth":1087,"text":4819},{"id":4869,"depth":1087,"text":4870},{"id":4885,"depth":1087,"text":4886,"children":5567},[5568],{"id":4906,"depth":1095,"text":4907},{"id":4936,"depth":1087,"text":4937,"children":5570},[5571],{"id":4968,"depth":1095,"text":4969},{"id":5010,"depth":1087,"text":5011,"children":5573},[5574],{"id":5040,"depth":1095,"text":5041},{"id":5075,"depth":1087,"text":5076},{"id":5098,"depth":1087,"text":5099},{"id":5143,"depth":1087,"text":5144},{"id":5169,"depth":1087,"text":5170},{"id":5199,"depth":1087,"text":5200},{"id":5214,"depth":1087,"text":5217},{"id":5229,"depth":1087,"text":5230,"children":5582},[5583,5584],{"id":5265,"depth":1095,"text":5266},{"id":5298,"depth":1095,"text":5299},{"id":5334,"depth":1087,"text":5335,"children":5586},[5587,5588],{"id":5368,"depth":1095,"text":5369},{"id":5393,"depth":1095,"text":5394},{"id":977,"depth":1087,"text":980},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"Practice the core Git workflow with small changes, branches, pull requests, and two guided troubleshooting scenarios.","Face-to-face class of about 40 students; includes command explanation, branch practice, pull request walkthrough, conflict exploration, and recovery discussion.","90",{},"40","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",{"title":4680,"description":5592},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[1134,5601,5602],"branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":5609,"title":5610,"audience":6,"body":5611,"contentType":1116,"course":1117,"description":6381,"estimateBasis":6382,"estimatedDiscussionMinutes":1621,"estimatedLiveMinutes":1623,"estimatedTotalMinutes":5596,"extension":1123,"meta":6383,"module":1125,"navigation":1126,"order":6384,"path":6385,"promptAssist":1128,"seo":6386,"status":1130,"stem":6387,"tags":6388,"videoDuration":6392,"videoId":6393,"videoLink":6394,"videoTitle":6395,"week":1125,"__hash__":6396},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup",{"type":8,"value":5612,"toc":6359},[5613,5630,5648,5669,5694,5728,5760,5838,5914,6016,6044,6109,6186,6210,6237,6255,6279,6330],[11,5614,5616,5619],{"id":5615,"level":14},"local-development-environment-title",[16,5617,5610],{"id":5618},"local-development-environment-setup",[24,5620,5621,5624,5627],{},[27,5622,5623],{},"VS Code for editing course files",[27,5625,5626],{},"Course profile for Internet Applications extensions",[27,5628,5629],{},"Optional local PHP check on your own computer",[11,5631,5632,5634],{"id":1704,"level":14},[16,5633,1707],{"id":1704},[24,5635,5636,5639,5642,5645],{},[27,5637,5638],{},"Install VS Code",[27,5640,5641],{},"Open the course repository root",[27,5643,5644],{},"Install the required extensions for the course",[27,5646,5647],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,5649,5651,5654],{"id":5650,"level":14},"what-this-setup-does",[16,5652,5653],{"id":5650},"What This Setup Does",[24,5655,5656,5659,5662],{},[27,5657,5658],{},"VS Code: editor for course files",[27,5660,5661],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[27,5663,5664,5665,5668],{},"Optional host PHP: quick ",[37,5666,5667],{},"php -v"," check and editor support",[11,5670,5672,5675],{"id":5671,"level":14},"step-1-install-vs-code",[16,5673,5674],{"id":5671},"Step 1: Install VS Code",[24,5676,5677,5685,5688,5691],{},[27,5678,5679,5680],{},"Download: ",[150,5681,5684],{"href":5682,"rel":5683},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[154],"Visual Studio Code",[27,5686,5687],{},"Install like a normal desktop app",[27,5689,5690],{},"Do not install VS Code inside your repository folder",[27,5692,5693],{},"VS Code is the editor; the repo is the workspace folder",[11,5695,5697,5700,5703,5725],{"id":5696,"level":14},"step-2-open-the-repository",[16,5698,5699],{"id":5696},"Step 2: Open The Repository",[20,5701,5702],{},"After the course repo is cloned:",[24,5704,5705,5714,5717,5722],{},[27,5706,5707,5708,560,5711],{},"VS Code -> ",[37,5709,5710],{},"File",[37,5712,5713],{},"Open Folder",[27,5715,5716],{},"Choose the repository root",[27,5718,5719,5720],{},"Folder name should match ",[37,5721,3771],{},[27,5723,5724],{},"Trust the workspace only if it is your cloned GitHub repo",[20,5726,5727],{},"Do not open a ZIP copy or clone the same repo again",[11,5729,5731,5735,5757],{"id":5730,"level":14},"step-3-create-course-profile",[16,5732,5734],{"id":5733},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[24,5736,5737,5743,5751,5754],{},[27,5738,5739,5740],{},"Gear icon -> ",[37,5741,5742],{},"Profiles",[27,5744,5745,5746,2296,5748],{},"Create ",[37,5747,1117],{},[37,5749,5750],{},"PHP",[27,5752,5753],{},"Switch into that profile",[27,5755,5756],{},"Install course extensions there",[20,5758,5759],{},"Profiles keep this course setup separate from other projects",[11,5761,5763,5766,5770],{"id":5762,"level":14},"step-4-install-extensions",[16,5764,5765],{"id":5762},"Step 4: Install Extensions",[173,5767,5769],{"id":5768},"start-with-these","Start With These",[24,5771,5772,5780,5788,5796,5804,5812,5827,5835],{},[27,5773,5774,5775],{},"Auto Rename Tag (Jun Han)\n",[24,5776,5777],{},[27,5778,5779],{},"Auto-completes matching HTML tags while you edit",[27,5781,5782,5783],{},"Bracket Lens (wraith13)\n",[24,5784,5785],{},[27,5786,5787],{},"Adds readability cues for closing brackets",[27,5789,5790,5791],{},"GitLens (GitKraken)\n",[24,5792,5793],{},[27,5794,5795],{},"Required: Git history, blame, and branch visibility in-editor",[27,5797,5798,5799],{},"MySQL (cweijan)\n",[24,5800,5801],{},[27,5802,5803],{},"Required later: connect to and inspect course database tables",[27,5805,5806,5807],{},"PHP Intelephense (Ben Mewburn)\n",[24,5808,5809],{},[27,5810,5811],{},"PHP language support, syntax checks, and warnings",[27,5813,5814,5815],{},"Todo Tree (Gruntfuggly)\n",[24,5816,5817],{},[27,5818,5819,5820,237,5823,5826],{},"Finds and lists ",[37,5821,5822],{},"TODO",[37,5824,5825],{},"FIXME",", and similar comments",[27,5828,5829,5830],{},"WakaTime\n",[24,5831,5832],{},[27,5833,5834],{},"Required in sections that use time tracking; needs your API key",[27,5836,5837],{},"See the slides below for MySQL and WakaTime setup",[11,5839,5841,5845],{"id":5840,"level":171},"step-4a-setup-mysql-extension",[16,5842,5844],{"id":5843},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[57,5846,5848,5906],{"gap":59,"left-width":2799,"right-width":3340,"align":5847},"center",[62,5849,5850,5854],{"v-slot:left":64},[173,5851,5853],{"id":5852},"connection-settings","Connection Settings",[24,5855,5856,5859,5903],{},[27,5857,5858],{},"Open the MySQL panel from the VS Code sidebar",[27,5860,5861,5862],{},"Create a new connection with your course database details",[24,5863,5864,5870,5876,5879,5882],{},[27,5865,5866,5867],{},"Host: ",[37,5868,5869],{},"db.ethereallab.app",[27,5871,5872,5873],{},"Port: ",[37,5874,5875],{},"3306",[27,5877,5878],{},"Username: your UCID",[27,5880,5881],{},"Database: your UCID",[27,5883,5884,5885],{},"Password: from your generated connection string\n",[24,5886,5887,5894],{},[27,5888,5889,5890],{},"Get it from the ",[150,5891,5893],{"href":694,"rel":5892},[154],"course database page",[27,5895,5896,5897,312,5900],{},"Use the 12 characters between ",[37,5898,5899],{},"ucid:",[37,5901,5902],{},"@",[27,5904,5905],{},"Save this connection; you will reuse it in later database lessons",[62,5907,5908],{"v-slot:right":64},[20,5909,5910],{},[1263,5911],{"alt":5912,"src":5913,"variant":1267},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png",[11,5915,5917,5921],{"id":5916,"level":171},"step-4b-setup-wakatime",[16,5918,5920],{"id":5919},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[57,5922,5924,5979],{"gap":59,"left-width":3748,"right-width":5923,"align":5847},"1.05fr",[62,5925,5926,5930],{"v-slot:left":64},[173,5927,5929],{"id":5928},"setup-order","Setup Order",[24,5931,5932,5939,5942,5945,5948,5951,5968,5973,5976],{},[27,5933,2773,5934],{},[150,5935,5938],{"href":5936,"rel":5937},"https:\u002F\u002Fwakatime.com\u002Fsignup",[154],"WakaTime",[27,5940,5941],{},"Create or open your account",[27,5943,5944],{},"Copy your API key from account settings",[27,5946,5947],{},"In VS Code, search Extensions for WakaTime",[27,5949,5950],{},"Install the WakaTime extension",[27,5952,5953,5954],{},"Open Command Palette:",[24,5955,5956,5962],{},[27,5957,5958,5959],{},"Windows\u002FLinux: ",[37,5960,5961],{},"Ctrl+Shift+P",[27,5963,5964,5965],{},"macOS: ",[37,5966,5967],{},"Cmd+Shift+P",[27,5969,3446,5970],{},[37,5971,5972],{},"WakaTime: API Key",[27,5974,5975],{},"Paste your API key",[27,5977,5978],{},"Restart VS Code if tracking does not appear right away",[62,5980,5981,5986,5993,5998,6005,6010],{"v-slot:right":64},[1282,5982,5983],{},[27,5984,5985],{},"WakaTime account settings:",[20,5987,5988],{},[1263,5989],{"alt":5990,"src":5991,"variant":1267,"max-height":5992},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[1282,5994,5995],{"start":1087},[27,5996,5997],{},"VS Code extension search:",[20,5999,6000],{},[1263,6001],{"alt":6002,"src":6003,"variant":1267,"max-height":6004},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[1282,6006,6007],{"start":1095},[27,6008,6009],{},"VS Code API key command:",[20,6011,6012],{},[1263,6013],{"alt":6014,"src":6015,"variant":1267,"max-height":6004},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,6017,6019,6022],{"id":6018,"level":14},"step-5-optional-local-php",[16,6020,6021],{"id":6018},"Step 5: Optional Local PHP",[24,6023,6024,6027,6030,6038,6041],{},[27,6025,6026],{},"Useful for editor support",[27,6028,6029],{},"Useful for quick terminal checks",[27,6031,6032,6033],{},"Not the main course runtime\n",[24,6034,6035],{},[27,6036,6037],{},"Viable backup solution if VM lesson has issues",[27,6039,6040],{},"VM and Render still run the real app path",[27,6042,6043],{},"See the slides below for OS-specific install notes",[11,6045,6047,6050],{"id":6046,"level":171},"step-5a-windows-php-zip",[16,6048,6049],{"id":6046},"Step 5A: Windows PHP ZIP",[57,6051,6052,6083],{"gap":59,"left-width":60,"right-width":60},[62,6053,6054,6058],{"v-slot:left":64},[173,6055,6057],{"id":6056},"download-and-extract","Download And Extract",[24,6059,6060,6063,6073,6078],{},[27,6061,6062],{},"Download PHP for Windows as a ZIP",[27,6064,6065,6066],{},"Extract it outside your repository",[24,6067,6068],{},[27,6069,1874,6070],{},[37,6071,6072],{},"C:\\tools\\php",[27,6074,6075,6076],{},"Add that extracted PHP folder to the user ",[37,6077,2565],{},[27,6079,6080,6081],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[37,6082,2565],{},[62,6084,6085,6089,6105],{"v-slot:right":64},[173,6086,6088],{"id":6087},"visual-checks","Visual Checks",[24,6090,6091,6097,6102],{},[27,6092,6093,6094],{},"The extracted folder contains ",[37,6095,6096],{},"php.exe",[27,6098,6099,6100],{},"The Path entry points to the folder, not to ",[37,6101,6096],{},[27,6103,6104],{},"A new terminal can run:",[69,6106],{"language":71,"src":6107,"label":6108},"\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,6110,6112,6115],{"id":6111,"level":171},"step-5b-macos-homebrew-php",[16,6113,6114],{"id":6111},"Step 5B: macOS Homebrew PHP",[57,6116,6117,6148],{"gap":59,"left-width":60,"right-width":60},[62,6118,6119,6123],{"v-slot:left":64},[173,6120,6122],{"id":6121},"install-homebrew","Install Homebrew",[24,6124,6125,6128,6136,6139,6142,6145],{},[27,6126,6127],{},"Open Terminal",[27,6129,6130,6131],{},"Copy the install command from ",[150,6132,6135],{"href":6133,"rel":6134},"https:\u002F\u002Fbrew.sh\u002F",[154],"brew.sh",[27,6137,6138],{},"Expect Terminal to ask for your Mac password",[27,6140,6141],{},"Expect Homebrew to mention Command Line Tools if needed",[27,6143,6144],{},"At the end, Homebrew may print \"Next steps\"",[27,6146,6147],{},"Run those \"Next steps\" commands if shown",[62,6149,6150,6154,6158,6161],{"v-slot:right":64},[173,6151,6153],{"id":6152},"then-install-php","Then Install PHP",[69,6155],{"language":71,"src":6156,"label":6157},"\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,6159,6160],{},"Look for:",[24,6162,6163,6169,6174,6180],{},[27,6164,6165,6168],{},[37,6166,6167],{},"brew --version"," prints a version",[27,6170,6171,6173],{},[37,6172,5667],{}," prints PHP 8 output",[27,6175,6176,6177],{},"Apple Silicon Macs commonly use ",[37,6178,6179],{},"\u002Fopt\u002Fhomebrew",[27,6181,6182,6183],{},"Intel Macs commonly use ",[37,6184,6185],{},"\u002Fusr\u002Flocal",[11,6187,6189,6193,6195,6199],{"id":6188,"level":171},"step-5c-linux-php-cli",[16,6190,6192],{"id":6191},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[20,6194,67],{},[69,6196],{"language":71,"src":6197,"label":6198},"\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,6200,6201,6204,6207],{},[27,6202,6203],{},"This installs command-line PHP",[27,6205,6206],{},"This is only for local terminal checks",[27,6208,6209],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,6211,6213,6216,6218,6221,6223,6226],{"id":6212,"level":14},"step-6-verify-optional-php",[16,6214,6215],{"id":6212},"Step 6: Verify Optional PHP",[20,6217,67],{},[69,6219],{"language":71,"src":6220},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[20,6222,78],{},[69,6224],{"language":213,"src":6225},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[24,6227,6228,6231,6234],{},[27,6229,6230],{},"Exact version can differ",[27,6232,6233],{},"PHP 8 output means the terminal can find PHP",[27,6235,6236],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,6238,6239,6241],{"id":977,"level":14},[16,6240,980],{"id":977},[24,6242,6243,6246,6249,6252],{},[27,6244,6245],{},"Installing tools inside the repository folder",[27,6247,6248],{},"Opening the parent folder instead of the repo root",[27,6250,6251],{},"Editing a ZIP copy instead of the cloned repo",[27,6253,6254],{},"Installing extensions in the wrong VS Code profile",[11,6256,6257,6259],{"id":875,"level":14},[16,6258,876],{"id":875},[24,6260,6261,6264,6267,6270,6273],{},[27,6262,6263],{},"VS Code opens your course repository root",[27,6265,6266],{},"Course profile is active",[27,6268,6269],{},"PHP Intelephense is installed",[27,6271,6272],{},"GitLens is installed",[27,6274,6275,6276,6278],{},"Optional: ",[37,6277,5667],{}," prints a PHP 8 version",[11,6280,6281,6283],{"id":2547,"level":14},[16,6282,2548],{"id":2547},[57,6284,6285,6303],{"gap":59,"left-width":60,"right-width":60},[62,6286,6287,6289],{"v-slot:left":64},[173,6288,1034],{"id":1031},[24,6290,6291,6294,6297,6300],{},[27,6292,6293],{},"IDE: editor with development tools",[27,6295,6296],{},"Extension: add-on that changes VS Code behavior",[27,6298,6299],{},"Profile: saved VS Code setup",[27,6301,6302],{},"PATH: system setting used to find commands",[62,6304,6305,6307],{"v-slot:right":64},[173,6306,2585],{"id":2544},[24,6308,6309,6316,6323],{},[27,6310,6311],{},[150,6312,6315],{"href":6313,"rel":6314},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[154],"VS Code Getting Started",[27,6317,6318],{},[150,6319,6322],{"href":6320,"rel":6321},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[154],"VS Code Profiles",[27,6324,6325],{},[150,6326,6329],{"href":6327,"rel":6328},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[154],"PHP Installation",[11,6331,6332,6334],{"id":1057,"level":14},[16,6333,1060],{"id":1057},[24,6335,6336,6339,6342,6345,6356],{},[27,6337,6338],{},"VS Code installed as the course editor",[27,6340,6341],{},"Repository opens from its root folder",[27,6343,6344],{},"Course extensions live in a course profile",[27,6346,6347,6348],{},"Local PHP is optional for this Internet Applications path\n",[24,6349,6350,6353],{},[27,6351,6352],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[27,6354,6355],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[27,6357,6358],{},"Next: copy the instructor template into the repository",{"title":64,"searchDepth":1087,"depth":1087,"links":6360},[6361,6362,6363,6364,6365,6366,6367,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380],{"id":5618,"depth":1087,"text":5610},{"id":1704,"depth":1087,"text":1707},{"id":5650,"depth":1087,"text":5653},{"id":5671,"depth":1087,"text":5674},{"id":5696,"depth":1087,"text":5699},{"id":5733,"depth":1087,"text":5734},{"id":5762,"depth":1087,"text":5765,"children":6368},[6369],{"id":5768,"depth":1095,"text":5769},{"id":5843,"depth":1087,"text":5844},{"id":5919,"depth":1087,"text":5920},{"id":6018,"depth":1087,"text":6021},{"id":6046,"depth":1087,"text":6049},{"id":6111,"depth":1087,"text":6114},{"id":6191,"depth":1087,"text":6192},{"id":6212,"depth":1087,"text":6215},{"id":977,"depth":1087,"text":980},{"id":875,"depth":1087,"text":876},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"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":5610,"description":6381},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[6389,6390,6391],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",{"id":4,"title":5,"audience":6,"body":6398,"contentType":1116,"course":1117,"description":1118,"estimateBasis":1119,"estimatedDiscussionMinutes":1120,"estimatedLiveMinutes":1121,"estimatedTotalMinutes":1122,"extension":1123,"meta":7167,"module":1125,"navigation":1126,"order":1122,"path":1127,"promptAssist":1128,"seo":7168,"status":1130,"stem":1131,"tags":7169,"videoDuration":1135,"videoId":1136,"videoLink":1137,"videoTitle":1138,"week":1125,"__hash__":1139},{"type":8,"value":6399,"toc":7142},[6400,6422,6454,6474,6497,6517,6549,6615,6647,6681,6715,6749,6803,6849,6902,6940,6992,7042,7064,7102,7120],[11,6401,6402,6404,6406],{"id":13,"level":14},[16,6403,18],{"id":13},[20,6405,22],{},[24,6407,6408,6410,6412,6416,6420],{},[27,6409,29],{},[27,6411,32],{},[27,6413,35,6414],{},[37,6415,39],{},[27,6417,42,6418],{},[37,6419,45],{},[27,6421,48],{},[11,6423,6424,6426],{"id":51,"level":14},[16,6425,55],{"id":54},[57,6427,6428,6434],{"gap":59,"left-width":60,"right-width":60},[62,6429,6430,6432],{"v-slot:left":64},[20,6431,67],{},[69,6433],{"language":71,"src":72,"label":73},[62,6435,6436,6438,6440],{"v-slot:right":64},[20,6437,78],{},[69,6439],{"language":81,"src":82,"label":83},[24,6441,6442,6446,6450],{},[27,6443,6444,91],{},[37,6445,90],{},[27,6447,6448,97],{},[37,6449,96],{},[27,6451,100,6452,103],{},[37,6453,90],{},[11,6455,6456,6458,6460,6462],{"id":106,"level":14},[16,6457,110],{"id":109},[20,6459,113],{},[69,6461],{"language":71,"src":116},[24,6463,6464,6468,6472],{},[27,6465,6466,123],{},[37,6467,37],{},[27,6469,6470,129],{},[37,6471,128],{},[27,6473,132],{},[11,6475,6476,6478],{"id":135,"level":14},[16,6477,139],{"id":138},[24,6479,6480,6489,6491,6493,6495],{},[27,6481,144,6482],{},[24,6483,6484],{},[27,6485,6486],{},[150,6487,155],{"href":152,"rel":6488},[154],[27,6490,158],{},[27,6492,161],{},[27,6494,164],{},[27,6496,167],{},[11,6498,6499,6501,6503,6505,6515],{"id":170,"level":171},[173,6500,176],{"id":175},[20,6502,179],{},[20,6504,182],{},[24,6506,6507,6509,6513],{},[27,6508,187],{},[27,6510,190,6511,194],{},[37,6512,193],{},[27,6514,197],{},[20,6516,200],{},[11,6518,6519,6521,6523,6525],{"id":203,"level":14},[16,6520,207],{"id":206},[20,6522,210],{},[69,6524],{"language":213,"src":214},[24,6526,6527,6531,6537,6547],{},[27,6528,6529,222],{},[37,6530,221],{},[27,6532,225,6533,229,6535],{},[37,6534,228],{},[37,6536,221],{},[27,6538,6539,237,6541,241,6543,245,6545],{},[37,6540,236],{},[37,6542,240],{},[37,6544,244],{},[37,6546,221],{},[27,6548,250],{},[11,6550,6551,6553,6613],{"id":253,"level":171},[173,6552,257],{"id":256},[24,6554,6555,6579,6595,6599,6603,6607,6611],{},[27,6556,6557,264,6559],{},[37,6558,221],{},[24,6560,6561,6567,6571,6575],{},[27,6562,6563,272,6565,276],{},[37,6564,271],{},[37,6566,275],{},[27,6568,6569,281],{},[37,6570,228],{},[27,6572,6573,287],{},[37,6574,286],{},[27,6576,6577,293],{},[37,6578,292],{},[27,6580,6581,298,6583],{},[37,6582,236],{},[24,6584,6585,6589],{},[27,6586,6587,306],{},[37,6588,305],{},[27,6590,6591,312,6593,316],{},[37,6592,311],{},[37,6594,315],{},[27,6596,6597,321],{},[37,6598,240],{},[27,6600,6601,326],{},[37,6602,244],{},[27,6604,6605,332],{},[37,6606,331],{},[27,6608,6609,338],{},[37,6610,337],{},[27,6612,341],{},[20,6614,344],{},[11,6616,6617,6619],{"id":347,"level":14},[16,6618,351],{"id":350},[57,6620,6621,6627],{"gap":59,"left-width":60,"right-width":60},[62,6622,6623,6625],{"v-slot:left":64},[20,6624,67],{},[69,6626],{"language":71,"src":360,"label":361},[62,6628,6629,6631,6633],{"v-slot:right":64},[20,6630,366],{},[69,6632],{"language":213,"src":369,"label":83},[24,6634,6635,6639,6643,6645],{},[27,6636,6637,377],{},[37,6638,376],{},[27,6640,380,6641],{},[37,6642,39],{},[27,6644,385],{},[27,6646,388],{},[11,6648,6649,6651],{"id":391,"level":14},[16,6650,395],{"id":394},[57,6652,6653,6659],{"gap":59,"left-width":60,"right-width":60},[62,6654,6655,6657],{"v-slot:left":64},[20,6656,67],{},[69,6658],{"language":71,"src":404,"label":405},[62,6660,6661,6663,6677,6679],{"v-slot:right":64},[20,6662,410],{},[24,6664,6665,6669,6673],{},[27,6666,6667,418],{},[37,6668,417],{},[27,6670,6671,423],{},[37,6672,128],{},[27,6674,6675,428],{},[37,6676,96],{},[20,6678,366],{},[69,6680],{"language":213,"src":433,"label":83},[11,6682,6683,6685],{"id":436,"level":14},[16,6684,440],{"id":439},[57,6686,6687,6693],{"gap":59,"left-width":60,"right-width":60},[62,6688,6689,6691],{"v-slot:left":64},[20,6690,67],{},[69,6692],{"language":71,"src":449,"label":450},[62,6694,6695,6697,6699],{"v-slot:right":64},[20,6696,366],{},[69,6698],{"language":213,"src":457,"label":83},[24,6700,6701,6705,6713],{},[27,6702,6703,465],{},[37,6704,464],{},[27,6706,6707,471,6709],{},[37,6708,470],{},[24,6710,6711],{},[27,6712,476],{},[27,6714,479],{},[11,6716,6717,6719],{"id":482,"level":14},[16,6718,486],{"id":485},[57,6720,6721,6727],{"gap":59,"left-width":60,"right-width":60},[62,6722,6723,6725],{"v-slot:left":64},[20,6724,67],{},[69,6726],{"language":71,"src":495,"label":496},[62,6728,6729,6731,6733],{"v-slot:right":64},[20,6730,366],{},[69,6732],{"language":213,"src":503,"label":83},[24,6734,6735,6739,6743,6747],{},[27,6736,6737,511],{},[37,6738,510],{},[27,6740,6741,517],{},[37,6742,516],{},[27,6744,6745,522],{},[37,6746,39],{},[27,6748,525],{},[11,6750,6751,6753],{"id":528,"level":14},[16,6752,532],{"id":531},[57,6754,6755,6789],{"gap":59,"left-width":60,"right-width":60},[62,6756,6757,6759],{"v-slot:left":64},[20,6758,539],{},[24,6760,6761,6763,6775,6779,6783,6785],{},[27,6762,544],{},[27,6764,547,6765,6767],{},[549,6766,551],{},[24,6768,6769],{},[27,6770,556,6771,560,6773],{},[549,6772,559],{},[549,6774,563],{},[27,6776,566,6777],{},[37,6778,45],{},[27,6780,571,6781],{},[37,6782,39],{},[27,6784,576],{},[27,6786,547,6787],{},[549,6788,581],{},[62,6790,6791,6793,6795],{"v-slot:right":64},[20,6792,586],{},[69,6794],{"language":213,"src":589,"label":590},[24,6796,6797,6799,6801],{},[27,6798,595],{},[27,6800,598],{},[27,6802,601],{},[11,6804,6805,6809],{"id":604,"level":14},[16,6806,608,6807],{"id":607},[37,6808,45],{},[57,6810,6811,6829],{"gap":59,"left-width":60,"right-width":60},[62,6812,6813,6815,6825,6827],{"v-slot:left":64},[20,6814,539],{},[24,6816,6817,6821],{},[27,6818,547,6819],{},[549,6820,623],{},[27,6822,547,6823],{},[549,6824,628],{},[20,6826,631],{},[69,6828],{"language":71,"src":634,"label":635},[62,6830,6831,6833,6835],{"v-slot:right":64},[20,6832,366],{},[69,6834],{"language":213,"src":642,"label":83},[24,6836,6837,6841,6845],{},[27,6838,6839,650],{},[37,6840,649],{},[27,6842,6843,656],{},[37,6844,655],{},[27,6846,659,6847,662],{},[37,6848,45],{},[11,6850,6851,6855],{"id":665,"level":14},[16,6852,668,6853],{"id":665},[37,6854,671],{},[57,6856,6857,6872],{"gap":59,"left-width":60,"right-width":60},[62,6858,6859,6861,6863],{"v-slot:left":64},[20,6860,678],{},[69,6862],{"language":71,"src":681,"label":682},[24,6864,6865],{},[27,6866,687,6867,691,6869],{},[37,6868,690],{},[150,6870,696],{"href":694,"rel":6871},[154],[62,6873,6874,6876,6878],{"v-slot:right":64},[20,6875,701],{},[69,6877],{"language":704,"src":705,"label":706},[24,6879,6880,6884,6888,6890,6894,6898],{},[27,6881,6882,713],{},[37,6883,671],{},[27,6885,716,6886,719],{},[37,6887,671],{},[27,6889,722],{},[27,6891,725,6892],{},[37,6893,690],{},[27,6895,6896,732],{},[37,6897,311],{},[27,6899,735,6900],{},[37,6901,311],{},[11,6903,6904,6906],{"id":740,"level":14},[16,6905,744],{"id":743},[57,6907,6908,6914],{"gap":59,"left-width":60,"right-width":60},[62,6909,6910,6912],{"v-slot:left":64},[20,6911,678],{},[69,6913],{"language":71,"src":753,"label":754},[62,6915,6916,6918,6920],{"v-slot:right":64},[20,6917,759],{},[69,6919],{"language":213,"src":762,"label":763},[24,6921,6922,6926,6930,6936],{},[27,6923,6924,771],{},[37,6925,770],{},[27,6927,6928,777],{},[37,6929,776],{},[27,6931,6932,782,6934,785],{},[37,6933,292],{},[37,6935,671],{},[27,6937,788,6938,792],{},[37,6939,791],{},[11,6941,6942,6946,6950],{"id":795,"level":14},[16,6943,799,6944,803],{"id":798},[37,6945,802],{},[20,6947,806,6948,128],{},[37,6949,809],{},[57,6951,6952,6974],{"gap":59,"left-width":60,"right-width":60},[62,6953,6954,6956,6958,6960],{"v-slot:left":64},[20,6955,816],{},[69,6957],{"language":71,"src":819,"label":820},[20,6959,823],{},[24,6961,6962,6966,6970],{},[27,6963,828,6964],{},[37,6965,831],{},[27,6967,834,6968],{},[37,6969,837],{},[27,6971,840,6972,843],{},[37,6973,837],{},[62,6975,6976,6978,6980,6982,6984],{"v-slot:right":64},[20,6977,848],{},[69,6979],{"language":851,"src":852,"label":837},[20,6981,855],{},[69,6983],{"language":71,"src":858,"label":859},[24,6985,6986,6990],{},[27,6987,864,6988],{},[37,6989,837],{},[27,6991,869],{},[11,6993,6994,6996,6998],{"id":872,"level":14},[16,6995,876],{"id":875},[20,6997,879],{},[24,6999,7000,7002,7008,7010,7014,7020,7024,7028,7032,7036],{},[27,7001,884],{},[27,7003,887,7004,890,7006],{},[37,7005,39],{},[37,7007,45],{},[27,7009,895],{},[27,7011,898,7012,901],{},[37,7013,45],{},[27,7015,7016,272,7018,910],{},[37,7017,906],{},[37,7019,909],{},[27,7021,7022,916],{},[37,7023,915],{},[27,7025,7026,921],{},[37,7027,221],{},[27,7029,7030,926],{},[37,7031,706],{},[27,7033,7034,932],{},[37,7035,931],{},[27,7037,935,7038,938,7040,941],{},[37,7039,802],{},[37,7041,292],{},[11,7043,7044,7046,7048,7050,7056],{"id":944,"level":14},[16,7045,948],{"id":947},[20,7047,67],{},[69,7049],{"language":71,"src":953},[955,7051,7052],{},[20,7053,959,7054,963],{},[37,7055,962],{},[24,7057,7058,7060,7062],{},[27,7059,968],{},[27,7061,971],{},[27,7063,974],{},[11,7065,7066,7068],{"id":977,"level":14},[16,7067,980],{"id":977},[24,7069,7070,7072,7074,7078,7080,7082,7086,7092,7096,7098],{},[27,7071,985],{},[27,7073,988],{},[27,7075,991,7076,194],{},[37,7077,193],{},[27,7079,996],{},[27,7081,999],{},[27,7083,1002,7084],{},[37,7085,221],{},[27,7087,1007,7088,1010,7090,1014],{},[37,7089,271],{},[37,7091,1013],{},[27,7093,1017,7094],{},[37,7095,45],{},[27,7097,1022],{},[27,7099,1025,7100,1028],{},[37,7101,45],{},[11,7103,7104,7106],{"id":1031,"level":14},[16,7105,1034],{"id":1031},[24,7107,7108,7110,7112,7114,7116,7118],{},[27,7109,1039],{},[27,7111,1042],{},[27,7113,1045],{},[27,7115,1048],{},[27,7117,1051],{},[27,7119,1054],{},[11,7121,7122,7124,7126],{"id":1057,"level":14},[16,7123,1060],{"id":1057},[20,7125,1063],{},[24,7127,7128,7130,7132,7134,7138],{},[27,7129,1068],{},[27,7131,1071],{},[27,7133,1074],{},[27,7135,1077,7136,1080],{},[37,7137,45],{},[27,7139,898,7140,1085],{},[37,7141,45],{},{"title":64,"searchDepth":1087,"depth":1087,"links":7143},[7144,7145,7146,7147,7150,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166],{"id":13,"depth":1087,"text":18},{"id":54,"depth":1087,"text":55},{"id":109,"depth":1087,"text":110},{"id":138,"depth":1087,"text":139,"children":7148},[7149],{"id":175,"depth":1095,"text":176},{"id":206,"depth":1087,"text":207,"children":7151},[7152],{"id":256,"depth":1095,"text":257},{"id":350,"depth":1087,"text":351},{"id":394,"depth":1087,"text":395},{"id":439,"depth":1087,"text":440},{"id":485,"depth":1087,"text":486},{"id":531,"depth":1087,"text":532},{"id":607,"depth":1087,"text":1105},{"id":665,"depth":1087,"text":1107},{"id":743,"depth":1087,"text":744},{"id":798,"depth":1087,"text":1110},{"id":875,"depth":1087,"text":876},{"id":947,"depth":1087,"text":948},{"id":977,"depth":1087,"text":980},{"id":1031,"depth":1087,"text":1034},{"id":1057,"depth":1087,"text":1060},{},{"title":5,"description":1118},[1133,62,1134],{"id":7171,"title":7172,"audience":6,"body":7173,"contentType":1116,"course":1117,"description":7883,"estimateBasis":7884,"estimatedDiscussionMinutes":1120,"estimatedLiveMinutes":5596,"estimatedTotalMinutes":2692,"extension":1123,"meta":7885,"module":1125,"navigation":1126,"order":4664,"path":7886,"promptAssist":1128,"seo":7887,"status":1130,"stem":7888,"tags":7889,"videoDuration":7891,"videoId":7892,"videoLink":7893,"videoTitle":7894,"week":1125,"__hash__":7895},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":7174,"toc":7862},[7175,7209,7257,7279,7333,7398,7456,7506,7571,7612,7704,7744,7771,7829],[11,7176,7177,7179,7181],{"id":13,"level":14},[16,7178,18],{"id":13},[20,7180,4689],{},[24,7182,7183,7192,7197,7201,7206],{},[27,7184,7185,7186,312,7189],{},"Understand the purpose and usage of ",[37,7187,7188],{},"qa",[37,7190,7191],{},"prod",[27,7193,7194,7195],{},"Create and push ",[37,7196,7188],{},[27,7198,7194,7199],{},[37,7200,7191],{},[27,7202,7203,7204],{},"Keep local work pointed at ",[37,7205,7188],{},[27,7207,7208],{},"Confirm GitHub has the expected branches",[11,7210,7212,7215,7250],{"id":7211,"level":14},"branch-roles",[16,7213,7214],{"id":7211},"Branch Roles",[24,7216,7217,7227,7237,7247],{},[27,7218,7219,7221,7222],{},[37,7220,45],{},": starter baseline and shared source branch\n",[24,7223,7224],{},[27,7225,7226],{},"Most projects stick with this; we'll split ours into development lanes",[27,7228,7229,7231,7232],{},[37,7230,7188],{},": public testing and evidence branch\n",[24,7233,7234],{},[27,7235,7236],{},"Normal branch to return to before new course work",[27,7238,7239,7241,7242],{},[37,7240,7191],{},": stable grading and evaluation branch\n",[24,7243,7244],{},[27,7245,7246],{},"Protected from everyday local edits",[27,7248,7249],{},"Later deployment setup connects Render to these branches",[20,7251,7252,7253,560,7255],{},"Course flow: feature or homework branch -> ",[37,7254,7188],{},[37,7256,7191],{},[11,7258,7259,7261,7264,7268],{"id":1739,"level":14},[16,7260,1742],{"id":1739},[20,7262,7263],{},"Run inside the course repository:",[69,7265],{"label":7266,"language":71,"src":7267},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[24,7269,7270,7273,7276],{},[27,7271,7272],{},"Working tree should be clean",[27,7274,7275],{},"Starter baseline already pushed to GitHub",[27,7277,7278],{},"Stop if Git says files are modified or untracked",[11,7280,7282,7288],{"id":7281,"level":14},"step-1-sync-main",[16,7283,7285,7286],{"id":7284},"step-1-start-from-main","Step 1: Start From ",[37,7287,45],{},[57,7289,7290,7298],{"gap":59,"left-width":60,"right-width":60},[62,7291,7292,7294],{"v-slot:left":64},[20,7293,67],{},[69,7295],{"label":7296,"language":71,"src":7297},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[62,7299,7300,7302,7305],{"v-slot:right":64},[20,7301,78],{},[69,7303],{"label":83,"language":213,"src":7304},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[24,7306,7307,7314],{},[27,7308,7309,7311,7312],{},[37,7310,649],{},": switch to ",[37,7313,45],{},[27,7315,7316,7318,7319,7321,7322],{},[37,7317,655],{},": get the latest ",[37,7320,45],{}," from GitHub\n",[24,7323,7324,7328],{},[27,7325,7326,511],{},[37,7327,510],{},[27,7329,7330,7332],{},[37,7331,45],{},": remote branch being pulled",[11,7334,7336,7342],{"id":7335,"level":14},"step-2-create-qa",[16,7337,7339,7340],{"id":7338},"step-2-create-and-push-qa","Step 2: Create And Push ",[37,7341,7188],{},[57,7343,7344,7352],{"gap":59,"left-width":60,"right-width":60},[62,7345,7346,7348],{"v-slot:left":64},[20,7347,67],{},[69,7349],{"label":7350,"language":71,"src":7351},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[62,7353,7354,7356,7359],{"v-slot:right":64},[20,7355,78],{},[69,7357],{"label":83,"language":213,"src":7358},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[24,7360,7361,7378],{},[27,7362,7363,7366,7367,7369,7370],{},[37,7364,7365],{},"git checkout -b qa",": create ",[37,7368,7188],{}," and switch to it\n",[24,7371,7372],{},[27,7373,7374,7377],{},[37,7375,7376],{},"-b",": creates a new branch of the following name",[27,7379,7380,7383,7384,7386,7387],{},[37,7381,7382],{},"git push -u origin qa",": send ",[37,7385,7188],{}," to GitHub\n",[24,7388,7389],{},[27,7390,7391,7393,7394,7397],{},[37,7392,516],{},": remember ",[37,7395,7396],{},"origin\u002Fqa"," as the upstream branch",[11,7399,7401,7407],{"id":7400,"level":14},"step-3-create-prod",[16,7402,7404,7405],{"id":7403},"step-3-create-and-push-prod","Step 3: Create And Push ",[37,7406,7191],{},[57,7408,7409,7417],{"gap":59,"left-width":60,"right-width":60},[62,7410,7411,7413],{"v-slot:left":64},[20,7412,67],{},[69,7414],{"label":7415,"language":71,"src":7416},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[62,7418,7419,7421,7424],{"v-slot:right":64},[20,7420,78],{},[69,7422],{"label":83,"language":213,"src":7423},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[24,7425,7426,7434,7439,7451],{},[27,7427,5745,7428,7430,7431,7433],{},[37,7429,7191],{}," from the current ",[37,7432,7188],{}," branch",[27,7435,7436],{},[37,7437,7438],{},"git checkout -b prod",[27,7440,7441,7442,7386,7444],{},"Push ",[37,7443,7191],{},[24,7445,7446],{},[27,7447,7448],{},[37,7449,7450],{},"git push origin prod",[27,7452,7453,7455],{},[37,7454,7191],{}," starts from the same clean baseline",[11,7457,7459,7464],{"id":7458,"level":14},"step-4-return-to-qa",[16,7460,7461,7462],{"id":7458},"Step 4: Return To ",[37,7463,7188],{},[57,7465,7466,7474],{"gap":59,"left-width":60,"right-width":60},[62,7467,7468,7470],{"v-slot:left":64},[20,7469,67],{},[69,7471],{"label":7472,"language":71,"src":7473},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[62,7475,7476,7478,7481],{"v-slot:right":64},[20,7477,78],{},[69,7479],{"label":83,"language":213,"src":7480},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[24,7482,7483,7488,7493],{},[27,7484,7485,7487],{},[37,7486,7188],{}," should have the asterisk",[27,7489,7490,7492],{},[37,7491,7191],{}," should still exist on GitHub",[27,7494,7495,7496,7498],{},"Do not start normal course work from ",[37,7497,7191],{},[24,7499,7500],{},[27,7501,7502,7503,7505],{},"We'll remove local ",[37,7504,7191],{}," to avoid this issue",[11,7507,7509,7515],{"id":7508,"level":14},"step-5-delete-local-prod",[16,7510,7512,7513],{"id":7511},"step-5-remove-local-prod","Step 5: Remove Local ",[37,7514,7191],{},[57,7516,7517,7525],{"gap":59,"left-width":60,"right-width":60},[62,7518,7519,7521],{"v-slot:left":64},[20,7520,67],{},[69,7522],{"label":7523,"language":71,"src":7524},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[62,7526,7527,7529,7532],{"v-slot:right":64},[20,7528,78],{},[69,7530],{"label":83,"language":213,"src":7531},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[24,7533,7534,7556],{},[27,7535,7536,7539,7540,7542],{},[37,7537,7538],{},"git branch -d prod",": delete local ",[37,7541,7191],{},[24,7543,7544,7550],{},[27,7545,7546,7549],{},[37,7547,7548],{},"-d",": delete only if Git considers it safe",[27,7551,7552,7555],{},[37,7553,7554],{},"-D",": can be used as a forced delete",[27,7557,7558,7561,7562],{},[37,7559,7560],{},"git branch -r",": list remote branches\n",[24,7563,7564],{},[27,7565,7566,7567,7570],{},"Confirms ",[37,7568,7569],{},"origin\u002Fprod"," still exists",[11,7572,7574,7577,7580,7583,7597,7600],{"id":7573,"level":14},"github-check",[16,7575,7576],{"id":7573},"GitHub Check",[20,7578,7579],{},"Open the branch dropdown on GitHub",[20,7581,7582],{},"You should see:",[24,7584,7585,7589,7593],{},[27,7586,7587],{},[37,7588,45],{},[27,7590,7591],{},[37,7592,7188],{},[27,7594,7595],{},[37,7596,7191],{},[20,7598,7599],{},"Branch roles:",[24,7601,7602,7607],{},[27,7603,7604,7606],{},[37,7605,7188],{},": testing and evidence",[27,7608,7609,7611],{},[37,7610,7191],{},": stable grading target",[11,7613,7615,7619],{"id":7614,"level":14},"normal-workflow",[16,7616,7618],{"id":7617},"normal-workflow-after-setup","Normal Workflow After Setup",[1282,7620,7621,7638,7646,7657,7662,7676,7679,7686,7698],{},[27,7622,7623,7624,7626],{},"Return to ",[37,7625,7188],{},[24,7627,7628,7633],{},[27,7629,7630],{},[37,7631,7632],{},"git checkout qa",[27,7634,7635],{},[37,7636,7637],{},"git pull origin qa",[27,7639,7640,7641],{},"Create a feature or homework branch\n",[24,7642,7643],{},[27,7644,7645],{},"Branch name matches the task",[27,7647,7648,7649],{},"Commit the work on that branch\n",[24,7650,7651],{},[27,7652,7653,7654,7656],{},"Check ",[37,7655,96],{}," before each Git command",[27,7658,7659,7660],{},"Push the branch and open a pull request into ",[37,7661,7188],{},[27,7663,7664,7665,7667,7668],{},"Merge into ",[37,7666,7188],{}," after review\n",[24,7669,7670],{},[27,7671,7672,7673,7675],{},"QA deployment will update from ",[37,7674,7188],{}," after Render setup",[27,7677,7678],{},"Test the QA version",[27,7680,7681,7682,890,7684],{},"Open a pull request from ",[37,7683,7188],{},[37,7685,7191],{},[27,7687,7664,7688,7690,7691],{},[37,7689,7191],{}," when stable\n",[24,7692,7693],{},[27,7694,7695,7696,7675],{},"Production deployment will use ",[37,7697,7191],{},[27,7699,7700,7701,7703],{},"Return locally to ",[37,7702,7188],{}," and pull before the next task",[11,7705,7706,7708],{"id":977,"level":14},[16,7707,980],{"id":977},[24,7709,7710,7715,7720,7728,7736,7739],{},[27,7711,7712,7713],{},"Working directly on ",[37,7714,7191],{},[27,7716,7717,7718],{},"Forgetting to return to ",[37,7719,7188],{},[27,7721,7722,7723,7725,7726],{},"Pushing ",[37,7724,7188],{}," but not ",[37,7727,7191],{},[27,7729,7730,7731,7733,7734],{},"Deleting remote ",[37,7732,7191],{}," instead of local ",[37,7735,7191],{},[27,7737,7738],{},"Assuming GitHub has the branch without checking",[27,7740,7741,7742,662],{},"Starting new work before ",[37,7743,96],{},[11,7745,7746,7748,7751],{"id":875,"level":14},[16,7747,876],{"id":875},[20,7749,7750],{},"Answer before moving on:",[24,7752,7753,7756,7759,7762,7768],{},[27,7754,7755],{},"Which branch should QA deployment watch?",[27,7757,7758],{},"Which branch should production grading use?",[27,7760,7761],{},"Which branch should you return to before new work?",[27,7763,7764,7765,7767],{},"Why remove local ",[37,7766,7191],{}," after pushing it?",[27,7769,7770],{},"What future setup connects Render to these branches?",[11,7772,7773,7775],{"id":2544,"level":14},[16,7774,2548],{"id":2547},[57,7776,7777,7802],{"gap":59,"left-width":60,"right-width":60},[62,7778,7779,7781],{"v-slot:left":64},[173,7780,1034],{"id":1031},[24,7782,7783,7786,7789,7794,7799],{},[27,7784,7785],{},"Branch: named line of Git history",[27,7787,7788],{},"Upstream: remote branch Git remembers for push\u002Fpull",[27,7790,7791,7793],{},[37,7792,7188],{},": public testing branch",[27,7795,7796,7798],{},[37,7797,7191],{},": stable grading branch",[27,7800,7801],{},"Remote-only branch: exists on GitHub, not locally",[62,7803,7804,7806],{"v-slot:right":64},[173,7805,2585],{"id":2544},[24,7807,7808,7815,7822],{},[27,7809,5498,7810],{},[150,7811,7814],{"href":7812,"rel":7813},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[154],"About branches",[27,7816,5498,7817],{},[150,7818,7821],{"href":7819,"rel":7820},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[154],"About pull requests",[27,7823,5483,7824],{},[150,7825,7828],{"href":7826,"rel":7827},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[154],"Git Branching",[11,7830,7831,7833,7835],{"id":1057,"level":14},[16,7832,1060],{"id":1057},[20,7834,2615],{},[24,7836,7837,7846,7850,7854,7859],{},[27,7838,7839,7840,237,7842,241,7844],{},"Explain ",[37,7841,45],{},[37,7843,7188],{},[37,7845,7191],{},[27,7847,7194,7848],{},[37,7849,7188],{},[27,7851,7194,7852],{},[37,7853,7191],{},[27,7855,7856,7857],{},"Keep local work branched from ",[37,7858,7188],{},[27,7860,7861],{},"Verify remote branches on GitHub",{"title":64,"searchDepth":1087,"depth":1087,"links":7863},[7864,7865,7866,7867,7869,7871,7873,7875,7877,7878,7879,7880,7881,7882],{"id":13,"depth":1087,"text":18},{"id":7211,"depth":1087,"text":7214},{"id":1739,"depth":1087,"text":1742},{"id":7284,"depth":1087,"text":7868},"Step 1: Start From main",{"id":7338,"depth":1087,"text":7870},"Step 2: Create And Push qa",{"id":7403,"depth":1087,"text":7872},"Step 3: Create And Push prod",{"id":7458,"depth":1087,"text":7874},"Step 4: Return To qa",{"id":7511,"depth":1087,"text":7876},"Step 5: Remove Local prod",{"id":7573,"depth":1087,"text":7576},{"id":7617,"depth":1087,"text":7618},{"id":977,"depth":1087,"text":980},{"id":875,"depth":1087,"text":876},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"Create the Internet Applications QA and production branches, then connect each branch to its role in the course workflow.","Face-to-face class of about 40 students; includes branch roles, command practice, GitHub branch checks, and QA\u002Fprod workflow questions.",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",{"title":7172,"description":7883},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[1134,5601,7188,7890],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":7897,"title":7898,"audience":6,"body":7899,"contentType":1116,"course":1117,"description":8706,"estimateBasis":8707,"estimatedDiscussionMinutes":1120,"estimatedLiveMinutes":2692,"estimatedTotalMinutes":4664,"extension":1123,"meta":8708,"module":1125,"navigation":1126,"order":8709,"path":8710,"promptAssist":1128,"seo":8711,"status":1130,"stem":8712,"tags":8713,"videoDuration":8716,"videoId":8717,"videoLink":8718,"videoTitle":8719,"week":1125,"__hash__":8720},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7900,"toc":8685},[7901,7928,7951,7980,8048,8109,8144,8180,8217,8267,8313,8348,8394,8431,8459,8491,8538,8571,8639],[11,7902,7904,7907],{"id":7903,"level":14},"render-setup-title",[16,7905,7898],{"id":7906},"render-setup",[24,7908,7909,7912,7917,7922,7925],{},[27,7910,7911],{},"Connect GitHub repo to Render",[27,7913,7914,7915],{},"Create a QA service from ",[37,7916,7188],{},[27,7918,7919,7920],{},"Create a production service from ",[37,7921,7191],{},[27,7923,7924],{},"Add the course database connection string",[27,7926,7927],{},"Verify live URLs and deploy logs",[11,7929,7930,7932,7934],{"id":3596,"level":14},[16,7931,3599],{"id":3596},[20,7933,4689],{},[24,7935,7936,7939,7942,7945,7948],{},[27,7937,7938],{},"Explain what Render does in the course workflow",[27,7940,7941],{},"Create separate QA and production services",[27,7943,7944],{},"Connect each service to the correct branch",[27,7946,7947],{},"Read Render logs when a deploy fails",[27,7949,7950],{},"Identify which deployed URL to submit or test",[11,7952,7954,7957,7974],{"id":7953,"level":14},"what-render-does",[16,7955,7956],{"id":7953},"What Render Does",[24,7958,7959,7962,7965,7968,7971],{},[27,7960,7961],{},"Hosts your PHP app from GitHub",[27,7963,7964],{},"Watches a selected branch",[27,7966,7967],{},"Rebuilds when that branch changes",[27,7969,7970],{},"Stores secrets as environment variables",[27,7972,7973],{},"Gives each service a public URL",[20,7975,7976,7977],{},"Course loop: ",[37,7978,7979],{},"local work -> GitHub branch -> Render URL",[11,7981,7983,7985],{"id":7982,"level":14},"free-tier-and-before-start",[16,7984,1742],{"id":1739},[57,7986,7987,8016],{"gap":59,"left-width":60,"right-width":60},[62,7988,7989,7993],{"v-slot:left":64},[173,7990,7992],{"id":7991},"free-tier","Free Tier",[24,7994,7995,8005,8013],{},[27,7996,3762,7997,8000],{},[37,7998,7999],{},"Free",[24,8001,8002],{},[27,8003,8004],{},"Render may default to a paid plan",[27,8006,8007,8008],{},"Free services can sleep",[24,8009,8010],{},[27,8011,8012],{},"First visit after sleep may be slow",[27,8014,8015],{},"Avoid extra services unless instructed",[62,8017,8018,8022],{"v-slot:right":64},[173,8019,8021],{"id":8020},"repo-ready","Repo Ready",[24,8023,8024,8027,8032,8041],{},[27,8025,8026],{},"Starter files committed and pushed",[27,8028,8029,8031],{},[37,8030,331],{}," in repo root",[27,8033,8034,237,8036,241,8038,8040],{},[37,8035,221],{},[37,8037,236],{},[37,8039,240],{}," present",[27,8042,8043,312,8045,8047],{},[37,8044,7188],{},[37,8046,7191],{}," branches exist on GitHub",[11,8049,8051,8054],{"id":8050,"level":14},"target-architecture",[16,8052,8053],{"id":8050},"Target Architecture",[57,8055,8056,8084],{"gap":59,"left-width":60,"right-width":60},[62,8057,8058,8062],{"v-slot:left":64},[173,8059,8061],{"id":8060},"qa-service","QA Service",[24,8063,8064,8070,8075,8078],{},[27,8065,8066,8067],{},"Name: ",[37,8068,8069],{},"\u003Cucid>-it202-\u003Csection>-qa",[27,8071,8072,8073],{},"Watches ",[37,8074,7188],{},[27,8076,8077],{},"Used for testing and evidence",[27,8079,8080,8081],{},"URL ends with ",[37,8082,8083],{},"-qa.onrender.com",[62,8085,8086,8090],{"v-slot:right":64},[173,8087,8089],{"id":8088},"production-service","Production Service",[24,8091,8092,8097,8101,8104],{},[27,8093,8066,8094],{},[37,8095,8096],{},"\u003Cucid>-it202-\u003Csection>-prod",[27,8098,8072,8099],{},[37,8100,7191],{},[27,8102,8103],{},"Stable version after QA checks",[27,8105,8080,8106],{},[37,8107,8108],{},"-prod.onrender.com",[11,8110,8112,8116],{"id":8111,"level":14},"step-1-sign-up",[16,8113,8115],{"id":8114},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[57,8117,8118,8136],{"gap":59,"left-width":3301,"right-width":3300},[62,8119,8120],{"v-slot:left":64},[24,8121,8122,8127,8130,8133],{},[27,8123,2773,8124],{},[37,8125,8126],{},"render.com",[27,8128,8129],{},"Choose GitHub sign-in",[27,8131,8132],{},"Authorize Render when prompted",[27,8134,8135],{},"Land on the Render dashboard",[62,8137,8138],{"v-slot:right":64},[20,8139,8140],{},[1263,8141],{"alt":8142,"src":8143,"variant":1267},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,8145,8147,8150],{"id":8146,"level":14},"step-2-new-web-service",[16,8148,8149],{"id":8146},"Step 2: New Web Service",[57,8151,8152,8172],{"gap":59,"left-width":3301,"right-width":3300},[62,8153,8154],{"v-slot:left":64},[24,8155,8156,8161,8166,8169],{},[27,8157,547,8158],{},[37,8159,8160],{},"New +",[27,8162,3762,8163],{},[37,8164,8165],{},"Web Service",[27,8167,8168],{},"Do not choose a database service here",[27,8170,8171],{},"This creates the hosted PHP app",[62,8173,8174],{"v-slot:right":64},[20,8175,8176],{},[1263,8177],{"alt":8178,"src":8179,"variant":1267},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,8181,8183,8187],{"id":8182,"level":14},"step-3-connect-repo",[16,8184,8186],{"id":8185},"step-3-connect-repository","Step 3: Connect Repository",[57,8188,8189,8209],{"gap":59,"left-width":2799,"right-width":3340},[62,8190,8191],{"v-slot:left":64},[24,8192,8193,8196,8199,8206],{},[27,8194,8195],{},"Select your student course repository",[27,8197,8198],{},"Authorize repository access if Render asks",[27,8200,8201,8202,8205],{},"Ensure it's the proper repository (format: ",[37,8203,8204],{},"ucid-course-section-semYear",")",[27,8207,8208],{},"Continue to service settings",[62,8210,8211],{"v-slot:right":64},[20,8212,8213],{},[1263,8214],{"alt":8215,"src":8216,"variant":1267},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,8218,8220,8224],{"id":8219,"level":14},"step-4-configure-qa",[16,8221,8223],{"id":8222},"step-4-configure-qa-service","Step 4: Configure QA Service",[57,8225,8226,8259],{"gap":59,"left-width":3301,"right-width":3300},[62,8227,8228,8231],{"v-slot:left":64},[20,8229,8230],{},"Use these settings:",[24,8232,8233,8237,8242,8248,8253,8256],{},[27,8234,8066,8235],{},[37,8236,8069],{},[27,8238,8239,8240],{},"Branch: ",[37,8241,7188],{},[27,8243,8244,8245],{},"Runtime: ",[37,8246,8247],{},"Docker",[27,8249,8250,8251],{},"Instance type: ",[37,8252,7999],{},[27,8254,8255],{},"Root directory: blank",[27,8257,8258],{},"Build\u002Fstart commands: blank",[62,8260,8261],{"v-slot:right":64},[20,8262,8263],{},[1263,8264],{"alt":8265,"src":8266,"variant":1267},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,8268,8270,8274],{"id":8269,"level":14},"step-5-env-vars",[16,8271,8273],{"id":8272},"step-5-add-environment-variables","Step 5: Add Environment Variables",[57,8275,8276,8305],{"gap":59,"left-width":3748,"right-width":5923},[62,8277,8278],{"v-slot:left":64},[24,8279,8280,8293,8299,8302],{},[27,8281,8282,8283,8285],{},"Add ",[37,8284,690],{},[24,8286,8287],{},[27,8288,8289,8290],{},"Get it from ",[150,8291,696],{"href":694,"rel":8292},[154],[27,8294,8295,8296,8298],{},"Do not use \"add from ",[37,8297,671],{},"\"",[27,8300,8301],{},"Add later API keys only when a later lesson requires them",[27,8303,8304],{},"Repeat required env vars on both QA and production",[62,8306,8307],{"v-slot:right":64},[20,8308,8309],{},[1263,8310],{"alt":8311,"src":8312,"variant":1267},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,8314,8316,8319],{"id":8315,"level":14},"step-6-deploy-qa",[16,8317,8318],{"id":8315},"Step 6: Deploy QA",[57,8320,8321,8340],{"gap":59,"left-width":2799,"right-width":3340},[62,8322,8323],{"v-slot:left":64},[24,8324,8325,8328,8331,8334,8337],{},[27,8326,8327],{},"Create the QA service",[27,8329,8330],{},"Watch the first deploy log",[27,8332,8333],{},"Wait for a success state",[27,8335,8336],{},"Open the QA URL",[27,8338,8339],{},"Confirm the starter page loads",[62,8341,8342],{"v-slot:right":64},[20,8343,8344],{},[1263,8345],{"alt":8346,"src":8347,"variant":1267},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,8349,8351,8355],{"id":8350,"level":14},"step-7-create-prod",[16,8352,8354],{"id":8353},"step-7-create-production-service","Step 7: Create Production Service",[57,8356,8357,8386],{"gap":59,"left-width":3301,"right-width":3300},[62,8358,8359,8362],{"v-slot:left":64},[20,8360,8361],{},"Create a second web service:",[24,8363,8364,8367,8371,8375,8379,8383],{},[27,8365,8366],{},"Same repository",[27,8368,8066,8369],{},[37,8370,8096],{},[27,8372,8239,8373],{},[37,8374,7191],{},[27,8376,8244,8377],{},[37,8378,8247],{},[27,8380,8250,8381],{},[37,8382,7999],{},[27,8384,8385],{},"Same required env vars",[62,8387,8388],{"v-slot:right":64},[20,8389,8390],{},[1263,8391],{"alt":8392,"src":8393,"variant":1267},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,8395,8396,8399],{"id":7614,"level":14},[16,8397,8398],{"id":7614},"Normal Workflow",[1282,8400,8401,8404,8407,8412,8415,8418,8421,8428],{},[27,8402,8403],{},"Work locally on a feature or homework branch",[27,8405,8406],{},"Commit and push that branch to GitHub",[27,8408,8409,8410],{},"Open a pull request into ",[37,8411,7188],{},[27,8413,8414],{},"Merge after review",[27,8416,8417],{},"Render updates the QA URL",[27,8419,8420],{},"Test the QA URL",[27,8422,7681,8423,890,8425,8427],{},[37,8424,7188],{},[37,8426,7191],{}," after evidence gathering",[27,8429,8430],{},"Render updates the production URL",[11,8432,8434,8437],{"id":8433,"level":14},"urls-and-cold-starts",[16,8435,8436],{"id":8433},"URLs And Cold Starts",[24,8438,8439,8442,8445,8448,8456],{},[27,8440,8441],{},"QA URL shows the test deployment",[27,8443,8444],{},"Production URL shows the stable deployment",[27,8446,8447],{},"Homework evidence usually starts with QA",[27,8449,8450,8451],{},"Free services may sleep after inactivity\n",[24,8452,8453],{},[27,8454,8455],{},"First visit after sleep may take extra time (2 - 5 minutes)",[27,8457,8458],{},"Do not submit before Render finishes deploying",[11,8460,8462,8465],{"id":8461,"level":14},"logs-and-status",[16,8463,8464],{"id":8461},"Logs And Status",[57,8466,8467,8483],{"gap":59,"left-width":2799,"right-width":3340},[62,8468,8469],{"v-slot:left":64},[24,8470,8471,8474,8477,8480],{},[27,8472,8473],{},"Logs show build and startup output",[27,8475,8476],{},"Dashboard status shows deploy progress",[27,8478,8479],{},"Failed deploys usually show the first useful clue",[27,8481,8482],{},"Read the first clear error before changing settings",[62,8484,8485],{"v-slot:right":64},[20,8486,8487],{},[1263,8488],{"alt":8489,"src":8490,"variant":1267},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8492,8494,8497],{"id":8493,"level":14},"troubleshooting",[16,8495,8496],{"id":8493},"Troubleshooting",[24,8498,8499,8509,8517,8527],{},[27,8500,8501,8502],{},"Build fails\n",[24,8503,8504],{},[27,8505,7653,8506,8508],{},[37,8507,331],{},", root directory, runtime, and instance type",[27,8510,8511,8512],{},"App deploys but page fails\n",[24,8513,8514],{},[27,8515,8516],{},"Check logs for PHP errors",[27,8518,8519,8520],{},"Database connection fails\n",[24,8521,8522],{},[27,8523,7653,8524,8526],{},[37,8525,690],{}," spelling and copied value",[27,8528,8529,8530],{},"Wrong version appears\n",[24,8531,8532,8535],{},[27,8533,8534],{},"Confirm the service watches the expected branch",[27,8536,8537],{},"Clear browser cache or test in a private window",[11,8539,8540,8542],{"id":977,"level":14},[16,8541,980],{"id":977},[24,8543,8544,8554,8557,8562,8565,8568],{},[27,8545,8546,8547,8549,8550,2296,8552],{},"Choosing ",[37,8548,45],{}," instead of ",[37,8551,7188],{},[37,8553,7191],{},[27,8555,8556],{},"Creating one service for both environments",[27,8558,8559,8560],{},"Forgetting ",[37,8561,690],{},[27,8563,8564],{},"Using a paid instance type by accident",[27,8566,8567],{},"Checking GitHub but not the Render URL",[27,8569,8570],{},"Changing code locally but forgetting to push and merge",[11,8572,8573,8575],{"id":2547,"level":14},[16,8574,2548],{"id":2547},[57,8576,8577,8605],{"gap":59,"left-width":60,"right-width":60},[62,8578,8579,8581,8587,8593,8599],{"v-slot:left":64},[173,8580,1034],{"id":1031},[20,8582,8583,8586],{},[549,8584,8585],{},"Service"," - one deployed app on Render",[20,8588,8589,8592],{},[549,8590,8591],{},"Watched branch"," - Git branch Render deploys from",[20,8594,8595,8598],{},[549,8596,8597],{},"Environment variable"," - setting stored outside code",[20,8600,8601,8604],{},[549,8602,8603],{},"Deploy log"," - output from Render's build\u002Fstart process",[62,8606,8607,8609],{"v-slot:right":64},[173,8608,2585],{"id":2544},[24,8610,8611,8618,8625,8632],{},[27,8612,8613],{},[150,8614,8617],{"href":8615,"rel":8616},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[154],"Render Docs: Web Services",[27,8619,8620],{},[150,8621,8624],{"href":8622,"rel":8623},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[154],"Render Docs: Deploys",[27,8626,8627],{},[150,8628,8631],{"href":8629,"rel":8630},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[154],"Render Docs: Environment Variables",[27,8633,8634],{},[150,8635,8638],{"href":8636,"rel":8637},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[154],"Render Docs: Free Instance Types",[11,8640,8641,8643,8646],{"id":1057,"level":14},[16,8642,1060],{"id":1057},[20,8644,8645],{},"Before leaving this presentation, confirm you:",[24,8647,8648,8651,8654,8661,8664,8667],{},[27,8649,8650],{},"Created QA and production Render services",[27,8652,8653],{},"Matched each service to the correct branch",[27,8655,8656,8657,691,8659],{},"Added ",[37,8658,690],{},[37,8660,696],{},[27,8662,8663],{},"Opened each deployed URL",[27,8665,8666],{},"Read logs instead of assuming it worked",[27,8668,8669,8670],{},"Understand the local -> GitHub -> Render loop\n",[24,8671,8672,8675,8680],{},[27,8673,8674],{},"Majority of your work will be done locally and tested locally",[27,8676,8677,8679],{},[37,8678,7188],{}," is just for gathering evidence for submissions",[27,8681,8682,8684],{},[37,8683,7191],{}," is what will be verified during grading",{"title":64,"searchDepth":1087,"depth":1087,"links":8686},[8687,8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705],{"id":7906,"depth":1087,"text":7898},{"id":3596,"depth":1087,"text":3599},{"id":7953,"depth":1087,"text":7956},{"id":1739,"depth":1087,"text":1742},{"id":8050,"depth":1087,"text":8053},{"id":8114,"depth":1087,"text":8115},{"id":8146,"depth":1087,"text":8149},{"id":8185,"depth":1087,"text":8186},{"id":8222,"depth":1087,"text":8223},{"id":8272,"depth":1087,"text":8273},{"id":8315,"depth":1087,"text":8318},{"id":8353,"depth":1087,"text":8354},{"id":7614,"depth":1087,"text":8398},{"id":8433,"depth":1087,"text":8436},{"id":8461,"depth":1087,"text":8464},{"id":8493,"depth":1087,"text":8496},{"id":977,"depth":1087,"text":980},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"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":7898,"description":8706},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8714,8715,7188,7890],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8722,"title":8723,"audience":6,"body":8724,"contentType":1116,"course":1117,"description":11398,"estimateBasis":11399,"estimatedDiscussionMinutes":11400,"estimatedLiveMinutes":11401,"estimatedTotalMinutes":11402,"extension":1123,"meta":11403,"module":1125,"navigation":1126,"order":5594,"path":11404,"promptAssist":1128,"seo":11405,"status":1130,"stem":11406,"tags":11407,"videoDuration":11412,"videoId":11413,"videoLink":11414,"videoTitle":11415,"week":1125,"__hash__":11416},"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":8725,"toc":11330},[8726,8755,8800,8836,8905,8937,8964,8996,9022,9051,9080,9107,9138,9166,9202,9267,9302,9348,9391,9435,9482,9545,9581,9616,9653,9686,9723,9756,9786,9816,9846,9876,9906,9940,9972,10004,10036,10085,10087,10130,10156,10197,10249,10328,10379,10410,10440,10470,10520,10545,10595,10643,10701,10759,10800,10830,10864,10898,10932,10983,11035,11054,11082,11130,11202,11302],[11,8727,8729,8732],{"id":8728,"level":14},"virtualbox-title",[16,8730,8723],{"id":8731},"local-ubuntu-web-server-with-virtualbox",[24,8733,8734,8737,8740,8743,8746,8752],{},[27,8735,8736],{},"Primary course path for the local Ubuntu VM",[27,8738,8739],{},"Create an Ubuntu Server VM in VirtualBox",[27,8741,8742],{},"Connect from your host terminal with SSH",[27,8744,8745],{},"Share the course repo into Ubuntu",[27,8747,8748,8749,8751],{},"Serve ",[37,8750,221],{}," through Apache and PHP",[27,8753,8754],{},"Create a local MySQL database for testing",[11,8756,8758,8761,8764,8775,8778],{"id":8757,"level":14},"main-goal",[16,8759,8760],{"id":8757},"Main Goal",[20,8762,8763],{},"Your host computer and Ubuntu VM have different jobs:",[24,8765,8766,8769,8772],{},[27,8767,8768],{},"Host computer: edit files with VS Code and open the browser",[27,8770,8771],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[27,8773,8774],{},"Shared folder: lets both use the same course repo files",[20,8776,8777],{},"Target result:",[24,8779,8780,8786,8791,8794,8797],{},[27,8781,8782,8783],{},"Host browser opens ",[37,8784,8785],{},"http:\u002F\u002Flocalhost:3000",[27,8787,8788,8789],{},"Apache serves the repo's ",[37,8790,221],{},[27,8792,8793],{},"PHP executes inside Ubuntu",[27,8795,8796],{},"Local MySQL has a database and user named after your UCID",[27,8798,8799],{},"Edits made on the host appear after browser refresh",[11,8801,8803,8806,8809,8828,8831],{"id":8802,"level":14},"virtualbox-caveat",[16,8804,8805],{"id":8802},"VirtualBox Caveat",[20,8807,8808],{},"VirtualBox is the primary local VM path for this course:",[24,8810,8811,8814,8817,8825],{},[27,8812,8813],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[27,8815,8816],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[27,8818,8819,8820],{},"Windows on Arm support is experimental in VirtualBox\n",[24,8821,8822],{},[27,8823,8824],{},"Avoid unless your instructor confirms it for your machine",[27,8826,8827],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[20,8829,8830],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[3013,8832,8833],{"type":4282},[20,8834,8835],{},"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,8837,8838,8840],{"id":1739,"level":14},[16,8839,1742],{"id":1739},[24,8841,8842,8860,8878,8881,8884,8887,8902],{},[27,8843,8844,8845],{},"VirtualBox downloaded\n",[24,8846,8847,8854,8857],{},[27,8848,8849],{},[150,8850,8853],{"href":8851,"rel":8852},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[154],"VirtualBox downloads",[27,8855,8856],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[27,8858,8859],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[27,8861,8862,8863],{},"Ubuntu Server ISO downloaded\n",[24,8864,8865,8872,8875],{},[27,8866,8867],{},[150,8868,8871],{"href":8869,"rel":8870},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[154],"Ubuntu Server installer",[27,8873,8874],{},"Apple Silicon Mac: use the ARM64 server ISO",[27,8876,8877],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[27,8879,8880],{},"Internet Applications course repo cloned on host computer",[27,8882,8883],{},"Git\u002FGitHub setup already working",[27,8885,8886],{},"Administrator access on your computer",[27,8888,8889,8890,8893,8894],{},"At least ",[37,8891,8892],{},"10 GB"," free disk space for the VM\n",[24,8895,8896],{},[27,8897,8898,8901],{},[37,8899,8900],{},"20-25 GB"," is safer if your computer has room",[27,8903,8904],{},"Stable internet for package installs",[11,8906,8908,8911],{"id":8907,"level":14},"setup-parts",[16,8909,8910],{"id":8907},"Setup Parts",[24,8912,8913,8916,8919,8922,8928,8931,8934],{},[27,8914,8915],{},"VM: Ubuntu Server running inside VirtualBox",[27,8917,8918],{},"NAT adapter: gives the VM internet access",[27,8920,8921],{},"Port forwarding: lets the host reach SSH and Apache",[27,8923,8924,8925],{},"SSH: lets the host terminal control Ubuntu through ",[37,8926,8927],{},"localhost",[27,8929,8930],{},"Shared folder: exposes the host repo inside Ubuntu",[27,8932,8933],{},"Apache\u002FPHP: serves and executes the web app",[27,8935,8936],{},"MySQL: local database server for local testing",[11,8938,8940,8944],{"id":8939,"level":14},"install-virtualbox-windows",[16,8941,8943],{"id":8942},"install-virtualbox-on-windows","Install VirtualBox On Windows",[24,8945,8946,8949,8952,8955,8958,8961],{},[27,8947,8948],{},"Download VirtualBox for Windows hosts",[27,8950,8951],{},"Run the installer as an administrator if prompted",[27,8953,8954],{},"Keep the default install path and features",[27,8956,8957],{},"Accept the network reset warning",[27,8959,8960],{},"Open VirtualBox after installation",[27,8962,8963],{},"See the slides below for the Windows installer screens",[11,8965,8967,8970],{"id":8966,"level":171},"windows-installer-start",[16,8968,8969],{"id":8966},"Windows Installer: Start",[57,8971,8972,8980],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,8973,8974],{"v-slot:left":64},[20,8975,8976],{},[1263,8977],{"alt":8978,"src":8979,"variant":1267},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[62,8981,8982],{"v-slot:right":64},[24,8983,8984,8990,8993],{},[27,8985,8986,8987],{},"Launch the downloaded ",[37,8988,8989],{},".exe",[27,8991,8992],{},"Approve the Windows security prompt if shown",[27,8994,8995],{},"Start the setup wizard",[11,8997,8999,9002],{"id":8998,"level":171},"windows-installer-features",[16,9000,9001],{"id":8998},"Windows Installer: Features",[57,9003,9004,9012],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9005,9006],{"v-slot:left":64},[20,9007,9008],{},[1263,9009],{"alt":9010,"src":9011,"variant":1267},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[62,9013,9014],{"v-slot:right":64},[24,9015,9016,9019],{},[27,9017,9018],{},"Keep the default install location",[27,9020,9021],{},"Keep the default features selected",[11,9023,9025,9028],{"id":9024,"level":171},"windows-installer-network-warning",[16,9026,9027],{"id":9024},"Windows Installer: Network Warning",[57,9029,9030,9038],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9031,9032],{"v-slot:left":64},[20,9033,9034],{},[1263,9035],{"alt":9036,"src":9037,"variant":1267},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[62,9039,9040],{"v-slot:right":64},[24,9041,9042,9045,9048],{},[27,9043,9044],{},"VirtualBox may reset network adapters briefly",[27,9046,9047],{},"This is expected during install",[27,9049,9050],{},"Save web work before continuing if needed",[11,9052,9054,9057],{"id":9053,"level":171},"windows-installer-ready",[16,9055,9056],{"id":9053},"Windows Installer: Ready",[57,9058,9059,9067],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9060,9061],{"v-slot:left":64},[20,9062,9063],{},[1263,9064],{"alt":9065,"src":9066,"variant":1267},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[62,9068,9069],{"v-slot:right":64},[24,9070,9071,9074,9077],{},[27,9072,9073],{},"Start the installation",[27,9075,9076],{},"Keep the default choices",[27,9078,9079],{},"Wait for the installer to request permissions if needed",[11,9081,9083,9087],{"id":9082,"level":171},"windows-installer-progress",[16,9084,9086],{"id":9085},"windows-installer-start-options","Windows Installer: Start Options",[57,9088,9089,9097],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9090,9091],{"v-slot:left":64},[20,9092,9093],{},[1263,9094],{"alt":9095,"src":9096,"variant":1267},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[62,9098,9099],{"v-slot:right":64},[24,9100,9101,9104],{},[27,9102,9103],{},"No need to create a Start Menu item or desktop shortcut unless desired",[27,9105,9106],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,9108,9110,9113],{"id":9109,"level":171},"windows-installer-permission",[16,9111,9112],{"id":9109},"Windows Installer: Permission",[57,9114,9115,9123],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9116,9117],{"v-slot:left":64},[20,9118,9119],{},[1263,9120],{"alt":9121,"src":9122,"variant":1267},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[62,9124,9125],{"v-slot:right":64},[24,9126,9127,9130],{},[27,9128,9129],{},"Proceed with install",[27,9131,9132,9133],{},"Approve VirtualBox driver prompts\n",[24,9134,9135],{},[27,9136,9137],{},"These let VirtualBox create virtual hardware",[11,9139,9141,9144],{"id":9140,"level":171},"windows-installer-complete",[16,9142,9143],{"id":9140},"Windows Installer: Complete",[57,9145,9146,9154],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9147,9148],{"v-slot:left":64},[20,9149,9150],{},[1263,9151],{"alt":9152,"src":9153,"variant":1267},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[62,9155,9156],{"v-slot:right":64},[24,9157,9158,9160,9163],{},[27,9159,3161],{},[27,9161,9162],{},"Open VirtualBox",[27,9164,9165],{},"Continue to VM creation",[11,9167,9169,9173],{"id":9168,"level":14},"install-virtualbox-macos",[16,9170,9172],{"id":9171},"install-virtualbox-on-macos","Install VirtualBox On macOS",[57,9174,9175,9194],{"gap":59,"left-width":3748,"right-width":5923,"stack":2800},[62,9176,9177],{"v-slot:left":64},[24,9178,9179,9182,9185,9188,9191],{},[27,9180,9181],{},"Install the VirtualBox host package for your Mac CPU type",[27,9183,9184],{},"Intel Mac: standard macOS host installer",[27,9186,9187],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[27,9189,9190],{},"Approve macOS security prompts if needed",[27,9192,9193],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[62,9195,9196],{"v-slot:right":64},[20,9197,9198],{},[1263,9199],{"alt":9200,"src":9201,"variant":1267},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,9203,9205,9209,9212],{"id":9204,"level":14},"step-1-create-vm",[16,9206,9208],{"id":9207},"step-1-create-the-vm","Step 1: Create The VM",[20,9210,9211],{},"Create a lightweight Ubuntu Server VM:",[24,9213,9214,9217,9225,9240,9252,9258,9261,9264],{},[27,9215,9216],{},"Type: Linux",[27,9218,9219,9220],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[24,9221,9222],{},[27,9223,9224],{},"Match the version to the ISO you downloaded",[27,9226,9227,9228,9231,9232],{},"Memory: ",[37,9229,9230],{},"1 GB"," course target\n",[24,9233,9234],{},[27,9235,2245,9236,9239],{},[37,9237,9238],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[27,9241,9242,9243,9245,9246],{},"Disk: ",[37,9244,8892],{}," course minimum\n",[24,9247,9248],{},[27,9249,9250,8901],{},[37,9251,8900],{},[27,9253,9254,9255,9257],{},"CPU: ",[37,9256,1125],{}," core is enough for this course VM",[27,9259,9260],{},"Enable OpenSSH during install if prompted",[27,9262,9263],{},"Username: use your UCID",[27,9265,9266],{},"See the slides below for VM settings and Ubuntu install screens",[11,9268,9270,9273],{"id":9269,"level":171},"vm-setup-name-and-iso",[16,9271,9272],{"id":9269},"VM Setup: Name And ISO",[57,9274,9275,9283],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9276,9277],{"v-slot:left":64},[20,9278,9279],{},[1263,9280],{"alt":9281,"src":9282,"variant":1267},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[62,9284,9285],{"v-slot:right":64},[24,9286,9287,9290,9296,9299],{},[27,9288,9289],{},"Start a new virtual machine",[27,9291,9292,9293],{},"Name it clearly, such as ",[37,9294,9295],{},"it202-vm",[27,9297,9298],{},"Choose the Ubuntu Server ISO file next",[27,9300,9301],{},"OS fields may look wrong until the ISO is selected",[11,9303,9305,9308],{"id":9304,"level":171},"vm-setup-confirm-ubuntu-iso",[16,9306,9307],{"id":9304},"VM Setup: Confirm Ubuntu ISO",[57,9309,9310,9318],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9311,9312],{"v-slot:left":64},[20,9313,9314],{},[1263,9315],{"alt":9316,"src":9317,"variant":1267},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[62,9319,9320],{"v-slot:right":64},[24,9321,9322,9328,9334,9337],{},[27,9323,9324,9325],{},"Confirm OS is ",[37,9326,9327],{},"Linux",[27,9329,9330,9331],{},"Confirm distribution is ",[37,9332,9333],{},"Ubuntu",[27,9335,9336],{},"Confirm version matches your ISO",[27,9338,716,9339,9342,9343],{},[37,9340,9341],{},"Unattended Installation"," off\n",[24,9344,9345],{},[27,9346,9347],{},"The Ubuntu installer screens are easier to teach manually",[11,9349,9351,9354],{"id":9350,"level":171},"vm-setup-memory-and-cpu",[16,9352,9353],{"id":9350},"VM Setup: Memory And CPU",[57,9355,9356,9364],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9357,9358],{"v-slot:left":64},[20,9359,9360],{},[1263,9361],{"alt":9362,"src":9363,"variant":1267},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[62,9365,9366],{"v-slot:right":64},[24,9367,9368,9381,9385,9388],{},[27,9369,9227,9370,9231,9373],{},[37,9371,9372],{},"1024 MB",[24,9374,9375,9378],{},[27,9376,9377],{},"The goal is to match free-tier cloud services",[27,9379,9380],{},"Demonstrates that small apps can run with limited resources",[27,9382,9254,9383],{},[37,9384,1125],{},[27,9386,9387],{},"Keep EFI off unless your machine requires it",[27,9389,9390],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,9392,9394,9397],{"id":9393,"level":171},"vm-setup-virtual-disk",[16,9395,9396],{"id":9393},"VM Setup: Virtual Disk",[57,9398,9399,9407],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9400,9401],{"v-slot:left":64},[20,9402,9403],{},[1263,9404],{"alt":9405,"src":9406,"variant":1267},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[62,9408,9409],{"v-slot:right":64},[24,9410,9411,9417,9420,9432],{},[27,9412,9413,9414],{},"Disk type: ",[37,9415,9416],{},"VDI",[27,9418,9419],{},"Storage: dynamically allocated",[27,9421,9422,9423,9425],{},"Minimum: ",[37,9424,8892],{},[24,9426,9427],{},[27,9428,9429,9431],{},[37,9430,8900],{}," is safer if you have room",[27,9433,9434],{},"Dynamic disk uses space as needed, not all at once",[11,9436,9438,9441],{"id":9437,"level":171},"vm-setup-start-with-gui",[16,9439,9440],{"id":9437},"VM Setup: Start With GUI",[57,9442,9443,9451],{"gap":59,"left-width":2798,"right-width":2799,"stack":2800},[62,9444,9445],{"v-slot:left":64},[20,9446,9447],{},[1263,9448],{"alt":9449,"src":9450,"variant":1267},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[62,9452,9453],{"v-slot:right":64},[24,9454,9455,9458,9468,9471],{},[27,9456,9457],{},"Select the newly created VM",[27,9459,547,9460,9463],{},[37,9461,9462],{},"Start",[24,9464,9465],{},[27,9466,9467],{},"Choose the normal GUI start for the first boot",[27,9469,9470],{},"Complete the Ubuntu installer in the VM window",[27,9472,9473,9474],{},"After install and SSH setup, future starts can be headless\n",[24,9475,9476],{},[27,9477,9478,9479,9481],{},"You will connect with ",[37,9480,4672],{}," when you need the VM",[11,9483,9485,9489,9492],{"id":9484,"level":14},"ubuntu-installer",[16,9486,9488],{"id":9487},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[20,9490,9491],{},"Use the Ubuntu Server installer after the VM starts:",[24,9493,9494,9497,9500,9503,9506,9509,9542],{},[27,9495,9496],{},"Choose the default course options unless noted",[27,9498,9499],{},"Continue without updating the installer if instructed",[27,9501,9502],{},"Use your UCID for the Ubuntu username",[27,9504,9505],{},"Install OpenSSH server during setup",[27,9507,9508],{},"Skip optional server snaps",[27,9510,9511,9512],{},"Keyboard navigation:\n",[24,9513,9514,9521,9531,9537],{},[27,9515,9516,9520],{},[9517,9518,9519],"kbd",{},"Tab"," moves between fields and buttons",[27,9522,9523,9526,9527,9530],{},[9517,9524,9525],{},"Up"," \u002F ",[9517,9528,9529],{},"Down"," moves through lists",[27,9532,9533,9536],{},[9517,9534,9535],{},"Space"," toggles checkboxes",[27,9538,9539,9541],{},[9517,9540,2329],{}," confirms the selected option",[27,9543,9544],{},"See the slides below for the installer screens",[11,9546,9548,9552],{"id":9547,"level":171},"ubuntu-installer-boot-menu",[16,9549,9551],{"id":9550},"step-21-boot-menu","Step 2.1: Boot Menu",[57,9553,9556,9565],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},"1.75fr","0.65fr",[62,9557,9558],{"v-slot:left":64},[20,9559,9560],{},[1263,9561],{"alt":9562,"src":9563,"variant":9564},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[62,9566,9567],{"v-slot:right":64},[24,9568,9569,9574,9578],{},[27,9570,3762,9571],{},[37,9572,9573],{},"Try or Install Ubuntu Server",[27,9575,2361,9576],{},[9517,9577,2329],{},[27,9579,9580],{},"This starts the Ubuntu Server installer",[11,9582,9584,9588],{"id":9583,"level":171},"ubuntu-installer-language",[16,9585,9587],{"id":9586},"step-22-language","Step 2.2: Language",[57,9589,9590,9598],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9591,9592],{"v-slot:left":64},[20,9593,9594],{},[1263,9595],{"alt":9596,"src":9597,"variant":9564},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[62,9599,9600],{"v-slot:right":64},[24,9601,9602,9605,9611],{},[27,9603,9604],{},"Choose your preferred language",[27,9606,9607,9610],{},[37,9608,9609],{},"English"," is the expected course screenshot path",[27,9612,2361,9613,9615],{},[9517,9614,2329],{}," to continue",[11,9617,9619,9623],{"id":9618,"level":171},"ubuntu-installer-update",[16,9620,9622],{"id":9621},"step-23-update-prompt","Step 2.3: Update Prompt",[57,9624,9625,9633],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9626,9627],{"v-slot:left":64},[20,9628,9629],{},[1263,9630],{"alt":9631,"src":9632,"variant":9564},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[62,9634,9635],{"v-slot:right":64},[24,9636,9637,9647,9650],{},[27,9638,3762,9639,9642],{},[37,9640,9641],{},"Continue without updating",[24,9643,9644],{},[27,9645,9646],{},"If I forget to update the image, it's the second option",[27,9648,9649],{},"Keeps the install path consistent",[27,9651,9652],{},"Package updates happen after Ubuntu is installed",[11,9654,9656,9660],{"id":9655,"level":171},"ubuntu-installer-keyboard",[16,9657,9659],{"id":9658},"step-24-keyboard","Step 2.4: Keyboard",[57,9661,9662,9670],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9663,9664],{"v-slot:left":64},[20,9665,9666],{},[1263,9667],{"alt":9668,"src":9669,"variant":9564},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[62,9671,9672],{"v-slot:right":64},[24,9673,9674,9677,9683],{},[27,9675,9676],{},"Keep the detected keyboard layout if it matches",[27,9678,9679,9680],{},"Common setting: ",[37,9681,9682],{},"English (US)",[27,9684,9685],{},"Use Identify keyboard only if typing is wrong",[11,9687,9689,9693],{"id":9688,"level":171},"ubuntu-installer-install-type",[16,9690,9692],{"id":9691},"step-25-install-type","Step 2.5: Install Type",[57,9694,9695,9703],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9696,9697],{"v-slot:left":64},[20,9698,9699],{},[1263,9700],{"alt":9701,"src":9702,"variant":9564},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[62,9704,9705],{"v-slot:right":64},[24,9706,9707,9717,9720],{},[27,9708,9709,9710,9713,9714],{},"Select ",[37,9711,9712],{},"Ubuntu Server (minimized)","; don't choose full ",[37,9715,9716],{},"Ubuntu Server",[27,9718,9719],{},"Keep third-party drivers unchecked",[27,9721,9722],{},"Minimized keeps the VM lighter and aids future lessons",[11,9724,9726,9730],{"id":9725,"level":171},"ubuntu-installer-network",[16,9727,9729],{"id":9728},"step-26-network","Step 2.6: Network",[57,9731,9732,9740],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9733,9734],{"v-slot:left":64},[20,9735,9736],{},[1263,9737],{"alt":9738,"src":9739,"variant":9564},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[62,9741,9742],{"v-slot:right":64},[24,9743,9744,9747,9753],{},[27,9745,9746],{},"DHCP address is expected",[27,9748,9749,9752],{},[37,9750,9751],{},"10.0.2.15"," is normal for VirtualBox NAT",[27,9754,9755],{},"Leave the network settings alone",[11,9757,9759,9763],{"id":9758,"level":171},"ubuntu-installer-proxy",[16,9760,9762],{"id":9761},"step-27-proxy","Step 2.7: Proxy",[57,9764,9765,9773],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9766,9767],{"v-slot:left":64},[20,9768,9769],{},[1263,9770],{"alt":9771,"src":9772,"variant":9564},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[62,9774,9775],{"v-slot:right":64},[24,9776,9777,9780,9783],{},[27,9778,9779],{},"Leave proxy blank",[27,9781,9782],{},"Only fill this in if your network requires a proxy",[27,9784,9785],{},"Most student home networks do not need one",[11,9787,9789,9793],{"id":9788,"level":171},"ubuntu-installer-mirror",[16,9790,9792],{"id":9791},"step-28-mirror","Step 2.8: Mirror",[57,9794,9795,9803],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9796,9797],{"v-slot:left":64},[20,9798,9799],{},[1263,9800],{"alt":9801,"src":9802,"variant":9564},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[62,9804,9805],{"v-slot:right":64},[24,9806,9807,9810,9813],{},[27,9808,9809],{},"Keep the default Ubuntu archive mirror",[27,9811,9812],{},"Wait for the mirror check to finish",[27,9814,9815],{},"Continue when the installer allows it",[11,9817,9819,9823],{"id":9818,"level":171},"ubuntu-installer-storage-guided",[16,9820,9822],{"id":9821},"step-29-guided-storage","Step 2.9: Guided Storage",[57,9824,9825,9833],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9826,9827],{"v-slot:left":64},[20,9828,9829],{},[1263,9830],{"alt":9831,"src":9832,"variant":9564},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[62,9834,9835],{"v-slot:right":64},[24,9836,9837,9840,9843],{},[27,9838,9839],{},"Use the entire virtual disk",[27,9841,9842],{},"LVM is optional, not needed for this course VM",[27,9844,9845],{},"Leave encryption off",[11,9847,9849,9853],{"id":9848,"level":171},"ubuntu-installer-storage-summary",[16,9850,9852],{"id":9851},"step-210-storage-summary","Step 2.10: Storage Summary",[57,9854,9855,9863],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9856,9857],{"v-slot:left":64},[20,9858,9859],{},[1263,9860],{"alt":9861,"src":9862,"variant":9564},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[62,9864,9865],{"v-slot:right":64},[24,9866,9867,9870,9873],{},[27,9868,9869],{},"Confirm the virtual disk is selected",[27,9871,9872],{},"This only affects the VM disk file",[27,9874,9875],{},"Continue when the layout looks correct",[11,9877,9879,9883],{"id":9878,"level":171},"ubuntu-installer-confirm-storage",[16,9880,9882],{"id":9881},"step-211-confirm-storage","Step 2.11: Confirm Storage",[57,9884,9885,9893],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9886,9887],{"v-slot:left":64},[20,9888,9889],{},[1263,9890],{"alt":9891,"src":9892,"variant":9564},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[62,9894,9895],{"v-slot:right":64},[24,9896,9897,9900,9903],{},[27,9898,9899],{},"Confirm the virtual disk format",[27,9901,9902],{},"This does not erase your host computer files",[27,9904,9905],{},"It formats the VM's virtual disk",[11,9907,9909,9913],{"id":9908,"level":171},"ubuntu-installer-profile",[16,9910,9912],{"id":9911},"step-212-profile","Step 2.12: Profile",[57,9914,9915,9923],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9916,9917],{"v-slot:left":64},[20,9918,9919],{},[1263,9920],{"alt":9921,"src":9922,"variant":9564},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[62,9924,9925],{"v-slot:right":64},[24,9926,9927,9930,9935,9937],{},[27,9928,9929],{},"Your name: your UCID or name is fine",[27,9931,9932,9933],{},"Server name: ",[37,9934,9295],{},[27,9936,5878],{},[27,9938,9939],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9941,9943,9947],{"id":9942,"level":171},"ubuntu-installer-pro",[16,9944,9946],{"id":9945},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[57,9948,9949,9957],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9950,9951],{"v-slot:left":64},[20,9952,9953],{},[1263,9954],{"alt":9955,"src":9956,"variant":9564},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[62,9958,9959],{"v-slot:right":64},[24,9960,9961,9966,9969],{},[27,9962,3762,9963],{},[37,9964,9965],{},"Skip for now",[27,9967,9968],{},"Ubuntu Pro is not needed for the course VM",[27,9970,9971],{},"You can continue without an Ubuntu account",[11,9973,9975,9979],{"id":9974,"level":171},"ubuntu-installer-ssh",[16,9976,9978],{"id":9977},"step-214-ssh","Step 2.14: SSH",[57,9980,9981,9989],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,9982,9983],{"v-slot:left":64},[20,9984,9985],{},[1263,9986],{"alt":9987,"src":9988,"variant":9564},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[62,9990,9991],{"v-slot:right":64},[24,9992,9993,9998,10001],{},[27,9994,7653,9995],{},[37,9996,9997],{},"Install OpenSSH server",[27,9999,10000],{},"Password authentication is fine for this local VM",[27,10002,10003],{},"No need to import SSH keys for this course setup",[11,10005,10007,10011],{"id":10006,"level":171},"ubuntu-installer-snaps",[16,10008,10010],{"id":10009},"step-215-featured-snaps","Step 2.15: Featured Snaps",[57,10012,10013,10021],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,10014,10015],{"v-slot:left":64},[20,10016,10017],{},[1263,10018],{"alt":10019,"src":10020,"variant":9564},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[62,10022,10023],{"v-slot:right":64},[24,10024,10025,10028,10033],{},[27,10026,10027],{},"Leave all featured snaps unchecked",[27,10029,10030,10031],{},"Apache, PHP, and MySQL are installed later with ",[37,10032,809],{},[27,10034,10035],{},"Continue without selecting extra packages",[11,10037,10039,10043],{"id":10038,"level":171},"ubuntu-installer-installing",[16,10040,10042],{"id":10041},"step-216-installing","Step 2.16: Installing",[57,10044,10045,10053],{"gap":1123,"left-width":9554,"right-width":9555,"stack":2800},[62,10046,10047],{"v-slot:left":64},[20,10048,10049],{},[1263,10050],{"alt":10051,"src":10052,"variant":9564},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[62,10054,10055,10080],{"v-slot:right":64},[24,10056,10057,10060,10063,10071,10077],{},[27,10058,10059],{},"Installation can take a while",[27,10061,10062],{},"High CPU during install is normal",[27,10064,10065,10066,10068,10069],{},"If install struggles at ",[37,10067,9230],{},", recreate the VM with ",[37,10070,9238],{},[27,10072,10073,10074,10076],{},"Keep the course target at ",[37,10075,9230],{}," after setup if possible",[27,10078,10079],{},"Reboot once complete",[3013,10081,10082],{"type":4282},[20,10083,10084],{},"These target resources stay close to common cloud free-tier VMs",[20,10086,3021],{},[11,10088,10090,10094,10097],{"id":10089,"level":14},"step-2-networking",[16,10091,10093],{"id":10092},"virtualbox-configure-networking","VirtualBox: Configure Networking",[20,10095,10096],{},"Use one NAT adapter with port forwarding:",[24,10098,10099,10105,10114,10122,10127],{},[27,10100,10101,10102],{},"VM internet: ",[37,10103,10104],{},"NAT",[27,10106,10107,10108,10111,10112],{},"Host SSH: host ",[37,10109,10110],{},"22"," -> guest ",[37,10113,10110],{},[27,10115,10116,10117,10111,10120],{},"Host browser: host ",[37,10118,10119],{},"3000",[37,10121,8709],{},[27,10123,2245,10124,10126],{},[37,10125,8927],{}," from the host computer",[27,10128,10129],{},"See the slides below for adapter and port-forwarding screens",[11,10131,10133,10137,10150],{"id":10132,"level":171},"adapter-settings-screen",[16,10134,10136],{"id":10135},"adapter-settings","Adapter Settings",[24,10138,10139,10142,10147],{},[27,10140,10141],{},"Adapter 1 enabled",[27,10143,10144,10145],{},"Attached to ",[37,10146,10104],{},[27,10148,10149],{},"No second adapter needed for the baseline path",[20,10151,10152],{},[1263,10153],{"alt":10154,"src":10155,"variant":9564},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,10157,10159,10163,10191],{"id":10158,"level":171},"port-forwarding-screen",[16,10160,10162],{"id":10161},"port-forwarding","Port Forwarding",[24,10164,10165,10173,10180],{},[27,10166,10167,10168,10170,10171],{},"SSH: host ",[37,10169,10110],{}," to guest ",[37,10172,10110],{},[27,10174,10175,10176,10170,10178],{},"Apache HTTP: host ",[37,10177,10119],{},[37,10179,8709],{},[27,10181,10182,10183,10185,10186,10170,10189],{},"If host ",[37,10184,10110],{}," is already busy, use host ",[37,10187,10188],{},"2222",[37,10190,10110],{},[20,10192,10193],{},[1263,10194],{"alt":10195,"src":10196,"variant":9564},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,10198,10200,10204,10207,10210,10213,10216],{"id":10199,"level":14},"step-3-connect-ssh",[16,10201,10203],{"id":10202},"step-3-connect-with-ssh","Step 3: Connect With SSH",[20,10205,10206],{},"Run from your host terminal:",[69,10208],{"language":71,"src":10209},"\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,10211,10212],{},"First connection prompt:",[69,10214],{"language":213,"src":10215},"\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,10217,10218,10225,10234,10237,10240],{},[27,10219,10220,10221,10224],{},"Replace ",[37,10222,10223],{},"your_ucid"," with your UCID",[27,10226,10227,10228,10230,10231,10233],{},"Type ",[37,10229,4209],{}," once for this course VM on ",[37,10232,8927],{}," (if prompted like the example above)",[27,10235,10236],{},"Enter your Ubuntu password",[27,10238,10239],{},"After login, commands run inside Ubuntu",[27,10241,10242,2296,10245,10248],{},[37,10243,10244],{},"exit",[37,10246,10247],{},"logout"," disconnects from the VM",[11,10250,10252,10256,10259],{"id":10251,"level":14},"step-4-confirm-network",[16,10253,10255],{"id":10254},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[20,10257,10258],{},"Run inside Ubuntu through SSH:",[57,10260,10261,10303],{"gap":59,"left-width":3340,"right-width":60,"stack":2800},[62,10262,10263,10266,10269],{"v-slot:left":64},[20,10264,10265],{},"Network check:",[69,10267],{"language":71,"src":10268},"\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,10270,10271,10277,10283,10289,10295],{},[27,10272,10273,10276],{},[37,10274,10275],{},"ping",": confirms basic network access",[27,10278,10279,10282],{},[37,10280,10281],{},"-c 4",": stop after four replies",[27,10284,10285,10288],{},[37,10286,10287],{},"apt update",": refreshes package indexes",[27,10290,10291,10294],{},[37,10292,10293],{},"apt upgrade",": applies available package updates",[27,10296,3258,10297,10299,10300],{},[37,10298,10275],{}," is not found, run ",[37,10301,10302],{},"sudo apt install iputils-ping",[62,10304,10305,10308,10311],{"v-slot:right":64},[20,10306,10307],{},"Port-forwarding check:",[69,10309],{"language":71,"src":10310},"\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,10312,10313,10318,10321,10325],{},[27,10314,10315,10316],{},"The VM may show ",[37,10317,9751],{},[27,10319,10320],{},"That is normal for VirtualBox NAT",[27,10322,2245,10323,10126],{},[37,10324,8927],{},[27,10326,10327],{},"Port forwarding routes host traffic into the VM",[11,10329,10331,10335],{"id":10330,"level":14},"step-5-shared-folder",[16,10332,10334],{"id":10333},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[57,10336,10337,10371],{"gap":59,"left-width":2799,"right-width":3340,"stack":2800},[62,10338,10339,10342],{"v-slot:left":64},[20,10340,10341],{},"In VirtualBox:",[24,10343,10344,10347,10350,10353,10356,10359,10362,10365,10368],{},[27,10345,10346],{},"Open VM settings",[27,10348,10349],{},"Choose Shared Folders",[27,10351,10352],{},"Folder Path: your cloned course repository folder",[27,10354,10355],{},"Folder Name: a simple repo name with no spaces",[27,10357,10358],{},"Mount Point: leave blank",[27,10360,10361],{},"Read-only: off",[27,10363,10364],{},"Auto-mount: on",[27,10366,10367],{},"Make Machine-permanent: on",[27,10369,10370],{},"Make Global: off",[62,10372,10373],{"v-slot:right":64},[20,10374,10375],{},[1263,10376],{"alt":10377,"src":10378,"variant":1267},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,10380,10382,10386,10389,10392],{"id":10381,"level":14},"step-6-guest-additions",[16,10383,10385],{"id":10384},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[20,10387,10388],{},"Run inside Ubuntu:",[69,10390],{"language":71,"src":10391},"\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,10393,10394,10401,10407],{},[27,10395,3446,10396,312,10398,10400],{},[37,10397,10287],{},[37,10399,10293],{}," first only if you skipped the Step 4 updates",[27,10402,10403,10406],{},[37,10404,10405],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[27,10408,10409],{},"Reboot after the group step on the next slide",[11,10411,10413,10417,10420,10423],{"id":10412,"level":171},"step-6b-confirm-vboxsf",[16,10414,10416],{"id":10415},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[20,10418,10419],{},"Reconnect with SSH, then run inside Ubuntu:",[69,10421],{"language":71,"src":10422},"\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,10424,10425,10431,10437],{},[27,10426,10427,10430],{},[37,10428,10429],{},"ls \u002Fmedia",": shows available mounted folders",[27,10432,10433,10436],{},[37,10434,10435],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[27,10438,10439],{},"Permission denied is common the first time",[11,10441,10443,10447,10450,10453],{"id":10442,"level":14},"step-7-locate-share",[16,10444,10446],{"id":10445},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[20,10448,10449],{},"If the shared folder exists but says permission denied:",[69,10451],{"language":71,"src":10452},"\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,10454,10455,10461,10467],{},[27,10456,10457,10460],{},[37,10458,10459],{},"vboxsf",": group allowed to read VirtualBox shared folders",[27,10462,10463,10466],{},[37,10464,10465],{},"$USER",": your Ubuntu login user for terminal access",[27,10468,10469],{},"Reboot applies the shared-folder support and new group membership",[11,10471,10473,10477,10479,10482,10499,10502],{"id":10472,"level":171},"step-7b-locate-share",[16,10474,10476],{"id":10475},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[20,10478,10419],{},[69,10480],{"language":71,"src":10481},"\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,10483,10484,10490,10496],{},[27,10485,10486,10489],{},[37,10487,10488],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[27,10491,10492,10495],{},[37,10493,10494],{},"\u003Cshared-folder>",": your shared course repo folder name",[27,10497,10498],{},"Use the folder that points to your repository",[20,10500,10501],{},"Expected repo folders:",[24,10503,10504,10508,10512,10516],{},[27,10505,10506],{},[37,10507,221],{},[27,10509,10510],{},[37,10511,236],{},[27,10513,10514],{},[37,10515,240],{},[27,10517,10518],{},[37,10519,244],{},[11,10521,10523,10527,10542],{"id":10522,"level":171},"step-7-2-shared-folder-check",[16,10524,10526],{"id":10525},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[24,10528,10529,10532,10539],{},[27,10530,10531],{},"Edit a small file from VS Code on host",[27,10533,3446,10534,2296,10536,10538],{},[37,10535,1912],{},[37,10537,2128],{}," inside Ubuntu",[27,10540,10541],{},"Confirm Ubuntu sees the same file content",[20,10543,10544],{},"If the file does not match, stop and fix the share before Apache setup",[11,10546,10548,10552,10554,10557],{"id":10547,"level":14},"step-8-install-apache-php-mysql",[16,10549,10551],{"id":10550},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[20,10553,10388],{},[69,10555],{"language":71,"src":10556},"\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,10558,10559,10565,10570,10576,10582,10588],{},[27,10560,10561,10564],{},[37,10562,10563],{},"apache2",": web server",[27,10566,10567,10569],{},[37,10568,6391],{},": PHP runtime",[27,10571,10572,10575],{},[37,10573,10574],{},"libapache2-mod-php",": lets Apache execute PHP files",[27,10577,10578,10581],{},[37,10579,10580],{},"mysql-server",": local MySQL database server",[27,10583,10584,10587],{},[37,10585,10586],{},"php-mysql",": lets PHP connect to MySQL",[27,10589,3446,10590,312,10592,10594],{},[37,10591,10287],{},[37,10593,10293],{}," first only if they have not been run recently",[11,10596,10598,10602,10609],{"id":10597,"level":171},"optional-swap-check",[16,10599,10601],{"id":10600},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[20,10603,10604,10605,10608],{},"Ubuntu usually has swap already. Only add this if ",[37,10606,10607],{},"swapon --show"," prints nothing.",[57,10610,10611,10625],{"gap":59,"left-width":60,"right-width":60},[62,10612,10613,10616,10619,10622],{"v-slot:left":64},[20,10614,10615],{},"Check first:",[69,10617],{"language":71,"src":10618},"\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,10620,10621],{},"Add a small swap file only if swap is off:",[69,10623],{"language":71,"src":10624},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[62,10626,10627],{"v-slot:right":64},[24,10628,10629,10632,10637,10640],{},[27,10630,10631],{},"Swap gives Ubuntu emergency disk-backed memory",[27,10633,10634,10635],{},"It helps when installs or MySQL briefly need more than ",[37,10636,9230],{},[27,10638,10639],{},"It is slower than RAM, so it is not a performance upgrade",[27,10641,10642],{},"Do not run the setup again if swap already exists",[11,10644,10646,10650,10656],{"id":10645,"level":171},"optional-apache-low-memory",[16,10647,10649],{"id":10648},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[20,10651,10652,10653,10655],{},"Use this if the ",[37,10654,9230],{}," VM feels unstable or Apache starts too many PHP workers.",[57,10657,10658,10671],{"gap":59,"left-width":60,"right-width":60},[62,10659,10660,10663,10668],{"v-slot:left":64},[20,10661,10662],{},"Edit Apache prefork settings in:",[20,10664,10665],{},[37,10666,10667],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[69,10669],{"language":71,"src":10670},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[62,10672,10673,10676,10680],{"v-slot:right":64},[20,10674,10675],{},"Change the existing values to:",[69,10677],{"language":10678,"src":10679},"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,10681,10682,10688,10691,10698],{},[27,10683,10684,10685],{},"Edit the existing lines inside ",[37,10686,10687],{},"\u003CIfModule mpm_prefork_module>",[27,10689,10690],{},"If a line is missing, add it inside that same block",[27,10692,10693,10694,10697],{},"Do not paste a second ",[37,10695,10696],{},"\u003CIfModule>"," block",[27,10699,10700],{},"Restart Apache after config changes",[11,10702,10704,10708,10714],{"id":10703,"level":171},"optional-mysql-low-memory",[16,10705,10707],{"id":10706},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[20,10709,10710,10711,10713],{},"Use this only if MySQL struggles on the ",[37,10712,9230],{}," VM.",[57,10715,10716,10729],{"gap":59,"left-width":60,"right-width":60},[62,10717,10718,10721,10726],{"v-slot:left":64},[20,10719,10720],{},"Edit MySQL server settings in:",[20,10722,10723],{},[37,10724,10725],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[69,10727],{"language":71,"src":10728},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[62,10730,10731,10737,10740],{"v-slot:right":64},[20,10732,10733,10734,2353],{},"Add or edit these under ",[37,10735,10736],{},"[mysqld]",[69,10738],{"language":851,"src":10739},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[24,10741,10742,10748,10753,10756],{},[27,10743,10744,10745,10747],{},"Keep these under the existing ",[37,10746,10736],{}," heading",[27,10749,10750,10751,10747],{},"Do not create a second ",[37,10752,10736],{},[27,10754,10755],{},"If either setting already exists, edit it instead of adding a duplicate",[27,10757,10758],{},"Restart MySQL after config changes",[11,10760,10762,10765,10768,10771],{"id":10761,"level":171},"low-memory-diagnostics",[16,10763,10764],{"id":10761},"Low Memory Diagnostics",[20,10766,10767],{},"Run these after the minor tuning checks:",[69,10769],{"language":71,"src":10770},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[24,10772,10773,10779,10784,10790,10797],{},[27,10774,10775,10778],{},[37,10776,10777],{},"free -h",": shows RAM and swap",[27,10780,10781,10783],{},[37,10782,10607],{},": confirms whether swap is active",[27,10785,10786,10789],{},[37,10787,10788],{},"systemctl status",": checks whether Apache and MySQL are running",[27,10791,10792,10793,10796],{},"No output from the ",[37,10794,10795],{},"grep"," line is usually good",[27,10798,10799],{},"Do not tune randomly; change one setting, restart, then retest",[11,10801,10803,10807,10809,10812,10815,10818],{"id":10802,"level":14},"step-9-create-local-mysql-db",[16,10804,10806],{"id":10805},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[20,10808,10388],{},[69,10810],{"language":71,"src":10811},"\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,10813,10814],{},"Then run in the MySQL prompt:",[69,10816],{"language":244,"src":10817},"\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,10819,10820,10824,10827],{},[27,10821,10220,10822,10224],{},[37,10823,10223],{},[27,10825,10826],{},"Database name and username should match your UCID",[27,10828,10829],{},"Password is local-only unless your instructor says otherwise",[11,10831,10833,10836,10839,10852,10855,10861],{"id":10832,"level":14},"local-vs-remote-database",[16,10834,10835],{"id":10832},"Local Vs Remote Database",[20,10837,10838],{},"This MySQL database is only for local testing:",[24,10840,10841,10845,10847,10849],{},[27,10842,5866,10843],{},[37,10844,8927],{},[27,10846,5881],{},[27,10848,5878],{},[27,10850,10851],{},"Password: your local password",[20,10853,10854],{},"Render uses the instructor-provided remote database connection string",[20,10856,10857,10858],{},"Get that string from ",[150,10859,694],{"href":694,"rel":10860},[154],[20,10862,10863],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10865,10867,10871,10873,10876,10878,10881,10884],{"id":10866,"level":14},"step-10-confirm-local-mysql",[16,10868,10870],{"id":10869},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[20,10872,10388],{},[69,10874],{"language":71,"src":10875},"\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,10877,631],{},[69,10879],{"language":244,"src":10880},"\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,10882,10883],{},"Expected:",[24,10885,10886,10892],{},[27,10887,10888,10891],{},[37,10889,10890],{},"SELECT DATABASE()"," returns your UCID",[27,10893,10894,10897],{},[37,10895,10896],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10899,10901,10907,10910,10913,10916],{"id":10900,"level":14},"step-11-documentroot",[16,10902,10904,10905],{"id":10903},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[37,10906,221],{},[20,10908,10909],{},"Apache should serve:",[69,10911],{"language":213,"src":10912},"\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,10914,10915],{},"Do not serve the whole repo",[24,10917,10918,10927],{},[27,10919,10920,237,10922,241,10924,10926],{},[37,10921,236],{},[37,10923,240],{},[37,10925,244],{}," stay outside the web root",[27,10928,10929,10931],{},[37,10930,221],{}," is the browser-facing folder",[11,10933,10935,10939,10942,10947,10949,10954,10957,10960],{"id":10934,"level":171},"apache-site-config",[16,10936,10938],{"id":10937},"step-111-apache-site-config","Step 11.1: Apache Site Config",[20,10940,10941],{},"Create or edit this Apache site config file inside Ubuntu:",[20,10943,10944],{},[37,10945,10946],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10948,67],{},[20,10950,10951],{},[37,10952,10953],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[20,10955,10956],{},"Add this content to that file:",[69,10958],{"language":10678,"src":10959},"\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,10961,10962,10967,10973,10978],{},[27,10963,10220,10964,10966],{},[37,10965,10494],{}," with the actual shared folder name",[27,10968,10969,10970],{},"Save the file as ",[37,10971,10972],{},"it202.conf",[27,10974,10975,10976],{},"Apache listens on guest port ",[37,10977,8709],{},[27,10979,10980,10981],{},"Host browser reaches it through ",[37,10982,8785],{},[11,10984,10986,10990,10992,10995],{"id":10985,"level":171},"enable-site",[16,10987,10989],{"id":10988},"step-112-enable-the-site","Step 11.2: Enable The Site",[20,10991,10388],{},[69,10993],{"language":71,"src":10994},"\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,10996,10997,11003,11009,11015,11023,11029],{},[27,10998,10999,11002],{},[37,11000,11001],{},"a2ensite",": enable a site config",[27,11004,11005,11008],{},[37,11006,11007],{},"a2dissite",": disable a site config",[27,11010,11011,11014],{},[37,11012,11013],{},"www-data",": Apache's user for browser requests",[27,11016,11017,11018,1010,11020,11022],{},"Adding ",[37,11019,11013],{},[37,11021,10459],{}," lets Apache read the shared folder",[27,11024,11025,11028],{},[37,11026,11027],{},"configtest",": check syntax before reload",[27,11030,11031,11034],{},[37,11032,11033],{},"restart",": applies the Apache user group change",[11,11036,11038,11042,11045,11048,11051],{"id":11037,"level":14},"step-12-php-check-page",[16,11039,11041],{"id":11040},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[20,11043,11044],{},"Create this file on the host:",[69,11046],{"language":213,"src":11047},"\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,11049,11050],{},"Example content:",[69,11052],{"language":6391,"src":11053},"\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,11055,11057,11060,11063,11066,11068],{"id":11056,"level":14},"final-browser-check",[16,11058,11059],{"id":11056},"Final Browser Check",[20,11061,11062],{},"Open from host browser:",[69,11064],{"language":213,"src":11065},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[20,11067,10883],{},[24,11069,11070,11073,11076,11079],{},[27,11071,11072],{},"Message appears",[27,11074,11075],{},"Time appears",[27,11077,11078],{},"PHP code is not shown as raw text",[27,11080,11081],{},"Editing the file on host changes output after refresh",[11,11083,11085,11088],{"id":11084,"level":14},"common-problems",[16,11086,11087],{"id":11084},"Common Problems",[24,11089,11090,11093,11096,11101,11104,11117,11127],{},[27,11091,11092],{},"Browser timeout: missing or wrong port-forwarding rule",[27,11094,11095],{},"Connection refused: Apache not running",[27,11097,11098,11099],{},"No internet in VM: check Adapter 1 is still ",[37,11100,10104],{},[27,11102,11103],{},"Shared folder missing: check Auto-mount and guest utilities",[27,11105,11106,11107,11110,11111,11113,11114,11116],{},"Browser shows ",[37,11108,11109],{},"403 Forbidden",": confirm ",[37,11112,11013],{}," is in ",[37,11115,10459],{},", then restart Apache or reboot",[27,11118,11119,11120,11123,11124,11126],{},"Permission denied on ",[37,11121,11122],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[37,11125,10459],{}," and reboot",[27,11128,11129],{},"Raw PHP code: PHP module not running through Apache",[11,11131,11133,11136,11139],{"id":11132,"level":14},"recovery-routine",[16,11134,11135],{"id":11132},"Recovery Routine",[20,11137,11138],{},"Check in this order:",[1282,11140,11141,11144,11150,11156,11161,11169,11176,11182,11187,11196],{},[27,11142,11143],{},"VM is running",[27,11145,11146,11149],{},[37,11147,11148],{},"ping github.com"," works inside Ubuntu",[27,11151,11152,11155],{},[37,11153,11154],{},"ssh username@localhost"," works from host",[27,11157,11158,11160],{},[37,11159,10435],{}," shows the shared repo",[27,11162,11163,11166,11167],{},[37,11164,11165],{},"groups"," includes ",[37,11168,10459],{},[27,11170,11171,11166,11174],{},[37,11172,11173],{},"id www-data",[37,11175,10459],{},[27,11177,11178,11181],{},[37,11179,11180],{},"sudo systemctl status apache2"," is active",[27,11183,11184,11181],{},[37,11185,11186],{},"sudo systemctl status mysql",[27,11188,11189,11192,11193],{},[37,11190,11191],{},"sudo apache2ctl configtest"," says ",[37,11194,11195],{},"Syntax OK",[27,11197,11198,11201],{},[37,11199,11200],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,11203,11204,11206],{"id":2547,"level":14},[16,11205,2548],{"id":2547},[57,11207,11208,11249],{"gap":59,"left-width":60,"right-width":60},[62,11209,11210,11212,11218,11227,11232,11238,11244],{"v-slot:left":64},[173,11211,1034],{"id":1031},[20,11213,11214,11217],{},[549,11215,11216],{},"VM"," - separate computer running inside your host computer",[20,11219,11220,11223,11224,11226],{},[549,11221,11222],{},"Port forwarding"," - host ",[37,11225,8927],{}," traffic routed into the VM",[20,11228,11229,11231],{},[549,11230,10459],{}," - VirtualBox shared-folder permission group",[20,11233,11234,11237],{},[549,11235,11236],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[20,11239,11240,11243],{},[549,11241,11242],{},"DocumentRoot"," - folder Apache serves to browsers",[20,11245,11246,11248],{},[549,11247,10104],{}," - VM network mode that gives the VM outbound internet access",[62,11250,11251,11253],{"v-slot:right":64},[173,11252,2585],{"id":2544},[24,11254,11255,11261,11268,11275,11282,11289,11295],{},[27,11256,11257],{},[150,11258,11260],{"href":8851,"rel":11259},[154],"VirtualBox Downloads",[27,11262,11263],{},[150,11264,11267],{"href":11265,"rel":11266},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[154],"VirtualBox Manual: Host And Guest Combinations",[27,11269,11270],{},[150,11271,11274],{"href":11272,"rel":11273},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[154],"VirtualBox Manual: Installation",[27,11276,11277],{},[150,11278,11281],{"href":11279,"rel":11280},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[154],"VirtualBox Manual: Shared Folders",[27,11283,11284],{},[150,11285,11288],{"href":11286,"rel":11287},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[154],"VirtualBox Manual: NAT Port Forwarding",[27,11290,11291],{},[150,11292,11294],{"href":8869,"rel":11293},[154],"Ubuntu Server: Installer",[27,11296,11297],{},[150,11298,11301],{"href":11299,"rel":11300},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[154],"Ubuntu Server: OpenSSH Server",[11,11303,11304,11306,11308],{"id":1057,"level":14},[16,11305,1060],{"id":1057},[20,11307,2615],{},[24,11309,11310,11313,11316,11319,11322,11327],{},[27,11311,11312],{},"Pick the correct Ubuntu ISO for your host CPU",[27,11314,11315],{},"Configure NAT port forwarding",[27,11317,11318],{},"Connect to Ubuntu with SSH",[27,11320,11321],{},"Find the VirtualBox shared repo",[27,11323,11324,11325],{},"Configure Apache to serve ",[37,11326,221],{},[27,11328,11329],{},"Create a local MySQL database and user named after your UCID",{"title":64,"searchDepth":1087,"depth":1087,"links":11331},[11332,11333,11334,11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378,11379,11380,11381,11382,11383,11384,11385,11386,11387,11388,11390,11391,11392,11393,11394,11395,11396,11397],{"id":8731,"depth":1087,"text":8723},{"id":8757,"depth":1087,"text":8760},{"id":8802,"depth":1087,"text":8805},{"id":1739,"depth":1087,"text":1742},{"id":8907,"depth":1087,"text":8910},{"id":8942,"depth":1087,"text":8943},{"id":8966,"depth":1087,"text":8969},{"id":8998,"depth":1087,"text":9001},{"id":9024,"depth":1087,"text":9027},{"id":9053,"depth":1087,"text":9056},{"id":9085,"depth":1087,"text":9086},{"id":9109,"depth":1087,"text":9112},{"id":9140,"depth":1087,"text":9143},{"id":9171,"depth":1087,"text":9172},{"id":9207,"depth":1087,"text":9208},{"id":9269,"depth":1087,"text":9272},{"id":9304,"depth":1087,"text":9307},{"id":9350,"depth":1087,"text":9353},{"id":9393,"depth":1087,"text":9396},{"id":9437,"depth":1087,"text":9440},{"id":9487,"depth":1087,"text":9488},{"id":9550,"depth":1087,"text":9551},{"id":9586,"depth":1087,"text":9587},{"id":9621,"depth":1087,"text":9622},{"id":9658,"depth":1087,"text":9659},{"id":9691,"depth":1087,"text":9692},{"id":9728,"depth":1087,"text":9729},{"id":9761,"depth":1087,"text":9762},{"id":9791,"depth":1087,"text":9792},{"id":9821,"depth":1087,"text":9822},{"id":9851,"depth":1087,"text":9852},{"id":9881,"depth":1087,"text":9882},{"id":9911,"depth":1087,"text":9912},{"id":9945,"depth":1087,"text":9946},{"id":9977,"depth":1087,"text":9978},{"id":10009,"depth":1087,"text":10010},{"id":10041,"depth":1087,"text":10042},{"id":10092,"depth":1087,"text":10093},{"id":10135,"depth":1087,"text":10136},{"id":10161,"depth":1087,"text":10162},{"id":10202,"depth":1087,"text":10203},{"id":10254,"depth":1087,"text":10255},{"id":10333,"depth":1087,"text":10334},{"id":10384,"depth":1087,"text":10385},{"id":10415,"depth":1087,"text":10416},{"id":10445,"depth":1087,"text":10446},{"id":10475,"depth":1087,"text":10476},{"id":10525,"depth":1087,"text":10526},{"id":10550,"depth":1087,"text":10551},{"id":10600,"depth":1087,"text":10601},{"id":10648,"depth":1087,"text":10649},{"id":10706,"depth":1087,"text":10707},{"id":10761,"depth":1087,"text":10764},{"id":10805,"depth":1087,"text":10806},{"id":10832,"depth":1087,"text":10835},{"id":10869,"depth":1087,"text":10870},{"id":10903,"depth":1087,"text":11389},"Step 11: Point Apache At public_html",{"id":10937,"depth":1087,"text":10938},{"id":10988,"depth":1087,"text":10989},{"id":11040,"depth":1087,"text":11041},{"id":11056,"depth":1087,"text":11059},{"id":11084,"depth":1087,"text":11087},{"id":11132,"depth":1087,"text":11135},{"id":2547,"depth":1087,"text":2548},{"id":1057,"depth":1087,"text":1060},"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":8723,"description":11398},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[11408,11409,10678,11410,11411],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581681351]