[{"data":1,"prerenderedAt":11208},["ShallowReactive",2],{"content-page:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment":3,"content-page-quiz:none":857,"book-module-total-pages":858,"content-section-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F":859,"content-directory-pages:\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment":11207},{"id":4,"title":5,"audience":6,"body":7,"contentType":832,"course":158,"description":833,"estimateBasis":834,"estimatedDiscussionMinutes":835,"estimatedLiveMinutes":836,"estimatedTotalMinutes":837,"extension":838,"meta":839,"module":840,"navigation":841,"order":842,"path":843,"promptAssist":844,"seo":845,"status":846,"stem":847,"tags":848,"videoDuration":852,"videoId":853,"videoLink":854,"videoTitle":855,"week":840,"__hash__":856},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment.md","Local Development Environment Setup","student",{"type":8,"value":9,"toc":810},"minimark",[10,32,52,74,101,138,172,252,339,447,475,545,622,647,676,696,722,779],[11,12,15,19],"slide",{"id":13,"level":14},"local-development-environment-title","2",[16,17,5],"h2",{"id":18},"local-development-environment-setup",[20,21,22,26,29],"ul",{},[23,24,25],"li",{},"VS Code for editing course files",[23,27,28],{},"Course profile for Internet Applications extensions",[23,30,31],{},"Optional local PHP check on your own computer",[11,33,35,38],{"id":34,"level":14},"goal",[16,36,37],{"id":34},"Goal",[20,39,40,43,46,49],{},[23,41,42],{},"Install VS Code",[23,44,45],{},"Open the course repository root",[23,47,48],{},"Install the required extensions for the course",[23,50,51],{},"Have a local php install as a light weight dev server (as a backup for the VM lessons)",[11,53,55,58],{"id":54,"level":14},"what-this-setup-does",[16,56,57],{"id":54},"What This Setup Does",[20,59,60,63,66],{},[23,61,62],{},"VS Code: editor for course files",[23,64,65],{},"Extensions: syntax help, Git visibility, database viewing, time tracking",[23,67,68,69,73],{},"Optional host PHP: quick ",[70,71,72],"code",{},"php -v"," check and editor support",[11,75,77,80],{"id":76,"level":14},"step-1-install-vs-code",[16,78,79],{"id":76},"Step 1: Install VS Code",[20,81,82,92,95,98],{},[23,83,84,85],{},"Download: ",[86,87,91],"a",{"href":88,"rel":89},"https:\u002F\u002Fcode.visualstudio.com\u002FDownload",[90],"nofollow","Visual Studio Code",[23,93,94],{},"Install like a normal desktop app",[23,96,97],{},"Do not install VS Code inside your repository folder",[23,99,100],{},"VS Code is the editor; the repo is the workspace folder",[11,102,104,107,111,135],{"id":103,"level":14},"step-2-open-the-repository",[16,105,106],{"id":103},"Step 2: Open The Repository",[108,109,110],"p",{},"After the course repo is cloned:",[20,112,113,123,126,132],{},[23,114,115,116,119,120],{},"VS Code -> ",[70,117,118],{},"File"," -> ",[70,121,122],{},"Open Folder",[23,124,125],{},"Choose the repository root",[23,127,128,129],{},"Folder name should match ",[70,130,131],{},"\u003Cucid>-IT202-\u003Csection>-\u003CsemYear>",[23,133,134],{},"Trust the workspace only if it is your cloned GitHub repo",[108,136,137],{},"Do not open a ZIP copy or clone the same repo again",[11,139,141,145,169],{"id":140,"level":14},"step-3-create-course-profile",[16,142,144],{"id":143},"step-3-create-a-course-profile","Step 3: Create A Course Profile",[20,146,147,153,163,166],{},[23,148,149,150],{},"Gear icon -> ",[70,151,152],{},"Profiles",[23,154,155,156,159,160],{},"Create ",[70,157,158],{},"Internet Applications"," or ",[70,161,162],{},"PHP",[23,164,165],{},"Switch into that profile",[23,167,168],{},"Install course extensions there",[108,170,171],{},"Profiles keep this course setup separate from other projects",[11,173,175,178,183],{"id":174,"level":14},"step-4-install-extensions",[16,176,177],{"id":174},"Step 4: Install Extensions",[179,180,182],"h3",{"id":181},"start-with-these","Start With These",[20,184,185,193,201,209,217,225,241,249],{},[23,186,187,188],{},"Auto Rename Tag (Jun Han)\n",[20,189,190],{},[23,191,192],{},"Auto-completes matching HTML tags while you edit",[23,194,195,196],{},"Bracket Lens (wraith13)\n",[20,197,198],{},[23,199,200],{},"Adds readability cues for closing brackets",[23,202,203,204],{},"GitLens (GitKraken)\n",[20,205,206],{},[23,207,208],{},"Required: Git history, blame, and branch visibility in-editor",[23,210,211,212],{},"MySQL (cweijan)\n",[20,213,214],{},[23,215,216],{},"Required later: connect to and inspect course database tables",[23,218,219,220],{},"PHP Intelephense (Ben Mewburn)\n",[20,221,222],{},[23,223,224],{},"PHP language support, syntax checks, and warnings",[23,226,227,228],{},"Todo Tree (Gruntfuggly)\n",[20,229,230],{},[23,231,232,233,236,237,240],{},"Finds and lists ",[70,234,235],{},"TODO",", ",[70,238,239],{},"FIXME",", and similar comments",[23,242,243,244],{},"WakaTime\n",[20,245,246],{},[23,247,248],{},"Required in sections that use time tracking; needs your API key",[23,250,251],{},"See the slides below for MySQL and WakaTime setup",[11,253,256,260],{"id":254,"level":255},"step-4a-setup-mysql-extension","3",[16,257,259],{"id":258},"step-4a-configure-mysql-extension","Step 4A: Configure MySQL Extension",[261,262,267,329],"two-col",{"gap":263,"left-width":264,"right-width":265,"align":266},"lg","0.9fr","1.1fr","center",[268,269,271,275],"template",{"v-slot:left":270},"",[179,272,274],{"id":273},"connection-settings","Connection Settings",[20,276,277,280,326],{},[23,278,279],{},"Open the MySQL panel from the VS Code sidebar",[23,281,282,283],{},"Create a new connection with your course database details",[20,284,285,291,297,300,303],{},[23,286,287,288],{},"Host: ",[70,289,290],{},"db.ethereallab.app",[23,292,293,294],{},"Port: ",[70,295,296],{},"3306",[23,298,299],{},"Username: your UCID",[23,301,302],{},"Database: your UCID",[23,304,305,306],{},"Password: from your generated connection string\n",[20,307,308,316],{},[23,309,310,311],{},"Get it from the ",[86,312,315],{"href":313,"rel":314},"https:\u002F\u002Fcourses.ethereallab.app\u002Fdatabase",[90],"course database page",[23,317,318,319,322,323],{},"Use the 12 characters between ",[70,320,321],{},"ucid:"," and ",[70,324,325],{},"@",[23,327,328],{},"Save this connection; you will reuse it in later database lessons",[268,330,331],{"v-slot:right":270},[108,332,333],{},[334,335],"img",{"alt":336,"src":337,"variant":338},"MySQL extension connection setup for the course database","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fmysql-setup.png","sidecar-screenshot",[11,340,342,346],{"id":341,"level":255},"step-4b-setup-wakatime",[16,343,345],{"id":344},"step-4b-configure-wakatime","Step 4B: Configure WakaTime",[261,347,350,407],{"gap":263,"left-width":348,"right-width":349,"align":266},"0.95fr","1.05fr",[268,351,352,356],{"v-slot:left":270},[179,353,355],{"id":354},"setup-order","Setup Order",[20,357,358,366,369,372,375,378,395,401,404],{},[23,359,360,361],{},"Go to ",[86,362,365],{"href":363,"rel":364},"https:\u002F\u002Fwakatime.com\u002Fsignup",[90],"WakaTime",[23,367,368],{},"Create or open your account",[23,370,371],{},"Copy your API key from account settings",[23,373,374],{},"In VS Code, search Extensions for WakaTime",[23,376,377],{},"Install the WakaTime extension",[23,379,380,381],{},"Open Command Palette:",[20,382,383,389],{},[23,384,385,386],{},"Windows\u002FLinux: ",[70,387,388],{},"Ctrl+Shift+P",[23,390,391,392],{},"macOS: ",[70,393,394],{},"Cmd+Shift+P",[23,396,397,398],{},"Run ",[70,399,400],{},"WakaTime: API Key",[23,402,403],{},"Paste your API key",[23,405,406],{},"Restart VS Code if tracking does not appear right away",[268,408,409,415,422,428,435,441],{"v-slot:right":270},[410,411,412],"ol",{},[23,413,414],{},"WakaTime account settings:",[108,416,417],{},[334,418],{"alt":419,"src":420,"variant":338,"max-height":421},"WakaTime account settings API key detail","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fsettings-api-key-detail.png","14rem",[410,423,425],{"start":424},2,[23,426,427],{},"VS Code extension search:",[108,429,430],{},[334,431],{"alt":432,"src":433,"variant":338,"max-height":434},"VS Code Extensions search results showing WakaTime","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-search.png","9rem",[410,436,438],{"start":437},3,[23,439,440],{},"VS Code API key command:",[108,442,443],{},[334,444],{"alt":445,"src":446,"variant":338,"max-height":434},"Command Palette with WakaTime API key command","\u002Fimages\u002Finternet-applications\u002Flocal-setup\u002Fwakatime\u002Fvs-code-prompt.png",[11,448,450,453],{"id":449,"level":14},"step-5-optional-local-php",[16,451,452],{"id":449},"Step 5: Optional Local PHP",[20,454,455,458,461,469,472],{},[23,456,457],{},"Useful for editor support",[23,459,460],{},"Useful for quick terminal checks",[23,462,463,464],{},"Not the main course runtime\n",[20,465,466],{},[23,467,468],{},"Viable backup solution if VM lesson has issues",[23,470,471],{},"VM and Render still run the real app path",[23,473,474],{},"See the slides below for OS-specific install notes",[11,476,478,481],{"id":477,"level":255},"step-5a-windows-php-zip",[16,479,480],{"id":477},"Step 5A: Windows PHP ZIP",[261,482,484,517],{"gap":263,"left-width":483,"right-width":483},"1fr",[268,485,486,490],{"v-slot:left":270},[179,487,489],{"id":488},"download-and-extract","Download And Extract",[20,491,492,495,506,512],{},[23,493,494],{},"Download PHP for Windows as a ZIP",[23,496,497,498],{},"Extract it outside your repository",[20,499,500],{},[23,501,502,503],{},"Example: ",[70,504,505],{},"C:\\tools\\php",[23,507,508,509],{},"Add that extracted PHP folder to the user ",[70,510,511],{},"Path",[23,513,514,515],{},"Restart Git Bash, PowerShell, and VS Code after editing ",[70,516,511],{},[268,518,519,523,539],{"v-slot:right":270},[179,520,522],{"id":521},"visual-checks","Visual Checks",[20,524,525,531,536],{},[23,526,527,528],{},"The extracted folder contains ",[70,529,530],{},"php.exe",[23,532,533,534],{},"The Path entry points to the folder, not to ",[70,535,530],{},[23,537,538],{},"A new terminal can run:",[540,541],"code-snippet",{"language":542,"src":543,"label":544},"bash","\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,546,548,551],{"id":547,"level":255},"step-5b-macos-homebrew-php",[16,549,550],{"id":547},"Step 5B: macOS Homebrew PHP",[261,552,553,584],{"gap":263,"left-width":483,"right-width":483},[268,554,555,559],{"v-slot:left":270},[179,556,558],{"id":557},"install-homebrew","Install Homebrew",[20,560,561,564,572,575,578,581],{},[23,562,563],{},"Open Terminal",[23,565,566,567],{},"Copy the install command from ",[86,568,571],{"href":569,"rel":570},"https:\u002F\u002Fbrew.sh\u002F",[90],"brew.sh",[23,573,574],{},"Expect Terminal to ask for your Mac password",[23,576,577],{},"Expect Homebrew to mention Command Line Tools if needed",[23,579,580],{},"At the end, Homebrew may print \"Next steps\"",[23,582,583],{},"Run those \"Next steps\" commands if shown",[268,585,586,590,594,597],{"v-slot:right":270},[179,587,589],{"id":588},"then-install-php","Then Install PHP",[540,591],{"language":542,"src":592,"label":593},"\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",[108,595,596],{},"Look for:",[20,598,599,605,610,616],{},[23,600,601,604],{},[70,602,603],{},"brew --version"," prints a version",[23,606,607,609],{},[70,608,72],{}," prints PHP 8 output",[23,611,612,613],{},"Apple Silicon Macs commonly use ",[70,614,615],{},"\u002Fopt\u002Fhomebrew",[23,617,618,619],{},"Intel Macs commonly use ",[70,620,621],{},"\u002Fusr\u002Flocal",[11,623,625,629,632,636],{"id":624,"level":255},"step-5c-linux-php-cli",[16,626,628],{"id":627},"step-5c-ubuntulinux-php-cli","Step 5C: Ubuntu\u002FLinux PHP CLI",[108,630,631],{},"Run:",[540,633],{"language":542,"src":634,"label":635},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Flinux-install-php-cli-05.sh","linux-php.sh",[20,637,638,641,644],{},[23,639,640],{},"This installs command-line PHP",[23,642,643],{},"This is only for local terminal checks",[23,645,646],{},"The later VM lesson installs Apache, PHP, and MySQL together",[11,648,650,653,655,658,661,665],{"id":649,"level":14},"step-6-verify-optional-php",[16,651,652],{"id":649},"Step 6: Verify Optional PHP",[108,654,631],{},[540,656],{"language":542,"src":657},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fstep-6-verify-optional-p-01.sh",[108,659,660],{},"Example output:",[540,662],{"language":663,"src":664},"text","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment\u002Fexample-output-02.txt",[20,666,667,670,673],{},[23,668,669],{},"Exact version can differ",[23,671,672],{},"PHP 8 output means the terminal can find PHP",[23,674,675],{},"Windows may need a terminal or VS Code restart after PATH changes",[11,677,679,682],{"id":678,"level":14},"common-mistakes",[16,680,681],{"id":678},"Common Mistakes",[20,683,684,687,690,693],{},[23,685,686],{},"Installing tools inside the repository folder",[23,688,689],{},"Opening the parent folder instead of the repo root",[23,691,692],{},"Editing a ZIP copy instead of the cloned repo",[23,694,695],{},"Installing extensions in the wrong VS Code profile",[11,697,699,702],{"id":698,"level":14},"quick-check",[16,700,701],{"id":698},"Quick Check",[20,703,704,707,710,713,716],{},[23,705,706],{},"VS Code opens your course repository root",[23,708,709],{},"Course profile is active",[23,711,712],{},"PHP Intelephense is installed",[23,714,715],{},"GitLens is installed",[23,717,718,719,721],{},"Optional: ",[70,720,72],{}," prints a PHP 8 version",[11,723,725,728],{"id":724,"level":14},"key-terms-and-further-learning",[16,726,727],{"id":724},"Key Terms And Further Learning",[261,729,730,750],{"gap":263,"left-width":483,"right-width":483},[268,731,732,736],{"v-slot:left":270},[179,733,735],{"id":734},"key-terms","Key Terms",[20,737,738,741,744,747],{},[23,739,740],{},"IDE: editor with development tools",[23,742,743],{},"Extension: add-on that changes VS Code behavior",[23,745,746],{},"Profile: saved VS Code setup",[23,748,749],{},"PATH: system setting used to find commands",[268,751,752,756],{"v-slot:right":270},[179,753,755],{"id":754},"further-learning","Further Learning",[20,757,758,765,772],{},[23,759,760],{},[86,761,764],{"href":762,"rel":763},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fintrovideos\u002Fbasics",[90],"VS Code Getting Started",[23,766,767],{},[86,768,771],{"href":769,"rel":770},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fconfigure\u002Fprofiles",[90],"VS Code Profiles",[23,773,774],{},[86,775,778],{"href":776,"rel":777},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.php",[90],"PHP Installation",[11,780,782,785],{"id":781,"level":14},"summary",[16,783,784],{"id":781},"Summary",[20,786,787,790,793,796,807],{},[23,788,789],{},"VS Code installed as the course editor",[23,791,792],{},"Repository opens from its root folder",[23,794,795],{},"Course extensions live in a course profile",[23,797,798,799],{},"Local PHP is optional for this Internet Applications path\n",[20,800,801,804],{},[23,802,803],{},"Summer 2026 added information about VM setup in a future lesson to teach clearer Apache\u002FMySQL topics",[23,805,806],{},"VM, Apache, Render QA, and Render production remain the real runtime checks",[23,808,809],{},"Next: copy the instructor template into the repository",{"title":270,"searchDepth":424,"depth":424,"links":811},[812,813,814,815,816,817,818,821,822,823,824,825,826,827,828,829,830,831],{"id":18,"depth":424,"text":5},{"id":34,"depth":424,"text":37},{"id":54,"depth":424,"text":57},{"id":76,"depth":424,"text":79},{"id":103,"depth":424,"text":106},{"id":143,"depth":424,"text":144},{"id":174,"depth":424,"text":177,"children":819},[820],{"id":181,"depth":437,"text":182},{"id":258,"depth":424,"text":259},{"id":344,"depth":424,"text":345},{"id":449,"depth":424,"text":452},{"id":477,"depth":424,"text":480},{"id":547,"depth":424,"text":550},{"id":627,"depth":424,"text":628},{"id":649,"depth":424,"text":652},{"id":678,"depth":424,"text":681},{"id":698,"depth":424,"text":701},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"presentation","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.","10","30","40","md",{},"1",true,"50","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",false,{"title":5,"description":833},"published","internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F05-setup-local-development-environment",[849,850,851],"vscode","local-development","php","44:26","0s1N-m3LABc","https:\u002F\u002Fyoutu.be\u002F0s1N-m3LABc","Local Development Environment setup","X5U0DDKjg7X7HrYtDDcsE4QqlBLimZ9weKgnZlc8H2s",null,[],[860,1353,2416,3300,4393,5330,5893,6960,7686,8511],{"id":861,"title":862,"audience":6,"body":863,"contentType":832,"course":158,"description":1335,"estimateBasis":1336,"estimatedDiscussionMinutes":835,"estimatedLiveMinutes":1337,"estimatedTotalMinutes":836,"extension":838,"meta":1338,"module":840,"navigation":841,"order":1339,"path":1340,"promptAssist":844,"seo":1341,"status":846,"stem":1342,"tags":1343,"videoDuration":1348,"videoId":1349,"videoLink":1350,"videoTitle":1351,"week":840,"__hash__":1352},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord.md","Learn Courses Platform And Discord",{"type":8,"value":864,"toc":1320},[865,899,939,984,1033,1081,1114,1176,1217,1267,1294],[11,866,868,872,886],{"id":867,"level":14},"learn-courses-flow",[16,869,871],{"id":870},"what-is-the-learn-courses-platform","What is the Learn Courses Platform",[20,873,874,877,880,883],{},[23,875,876],{},"This is a platform I've built over the years to aid assignment submissions and course utilities",[23,878,879],{},"It provides objective-based worksheets to fill in images, urls, and open responses to document assignment evidence",[23,881,882],{},"The goal is to keep tasks clear and objective for students and grading",[23,884,885],{},"Also includes a few other utilities for courses (such as joining the Discord server)",[108,887,888,889,893,894,898],{},"NOTE: Summer 2026 the previous Learn Platform (",[86,890,891],{"href":891,"rel":892},"https:\u002F\u002Flearn.ethereallab.app",[90],") has been replaced by Learn Courses Platform (",[86,895,896],{"href":896,"rel":897},"https:\u002F\u002Fcourses.ethereallab.app",[90],"). The deprecated site is still available as a backup but all activities\u002Fcontent is being migrated to the new version",[11,900,902,905,908,936],{"id":901,"level":14},"learn-courses-title",[16,903,862],{"id":904},"learn-courses-platform-and-discord",[108,906,907],{},"How to join:",[20,909,910,916,924,927,930,933],{},[23,911,912,913],{},"Visit the platform ",[86,914,896],{"href":896,"rel":915},[90],[23,917,918,919],{},"Sign in with your NJIT email\n",[20,920,921],{},[23,922,923],{},"If you're in the Canvas course, you should automatically get synced to this platform",[23,925,926],{},"Visit your Profile page",[23,928,929],{},"Associate your Discord account",[23,931,932],{},"Join the course Discord server",[23,934,935],{},"Verify that your course channels appear on Discord",[108,937,938],{},"You can follow the steps on the below slides for guidance",[11,940,942,945],{"id":941,"level":255},"visit-learn-courses",[16,943,944],{"id":941},"Visit Learn Courses",[261,946,947,976],{"gap":263,"left-width":483,"right-width":483},[268,948,949,952,957],{"v-slot:left":270},[108,950,951],{},"Go to:",[108,953,954],{},[86,955,896],{"href":896,"rel":956},[90],[20,958,959,967,970,973],{},[23,960,961,962,966],{},"Click the ",[963,964,965],"strong",{},"Login"," button",[23,968,969],{},"Use your NJIT email",[23,971,972],{},"Only NJIT accounts are allowed",[23,974,975],{},"If the browser tries a personal Chrome profile, log out of that account or switch profiles",[268,977,978],{"v-slot:right":270},[108,979,980],{},[334,981],{"alt":982,"src":983,"variant":338},"Learn Courses logged-out home page with the Login button visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fhome-loggedout-login-button.png",[11,985,987,990],{"id":986,"level":255},"associate-discord-name",[16,988,989],{"id":986},"Associate Discord Name",[261,991,992,1017],{"gap":263,"left-width":483,"right-width":483},[268,993,994,997,1014],{"v-slot:left":270},[108,995,996],{},"On Learn Courses:",[410,998,999,1002,1008,1011],{},[23,1000,1001],{},"Open your Profile",[23,1003,1004,1005],{},"Click ",[963,1006,1007],{},"Refresh Discord Username",[23,1009,1010],{},"Authorize the Discord prompt",[23,1012,1013],{},"After the success message appears, save your profile",[108,1015,1016],{},"If you are not sure where you are, use the Home icon in the top left to return to the dashboard.",[268,1018,1019,1026],{"v-slot:right":270},[108,1020,1021],{},[334,1022],{"alt":1023,"src":1024,"variant":338,"max-height":1025},"Learn Courses dashboard sidebar with Profile and course links visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdashboard-sidebar-profile-links.png","13rem",[108,1027,1028],{},[334,1029],{"alt":1030,"src":1031,"variant":338,"max-height":1032},"Learn Courses profile page with Discord connection controls visible","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fprofile-page.png","16rem",[11,1034,1036,1039],{"id":1035,"level":255},"authorize-discord",[16,1037,1038],{"id":1035},"Authorize Discord",[261,1040,1041,1065],{"gap":263,"left-width":483,"right-width":483},[268,1042,1043,1046],{"v-slot:left":270},[108,1044,1045],{},"Discord will ask whether Learn Courses can access your Discord account.",[20,1047,1048,1051,1056,1059,1062],{},[23,1049,1050],{},"Confirm you are signed in to the correct Discord account",[23,1052,1004,1053],{},[963,1054,1055],{},"Authorize",[23,1057,1058],{},"Return to Learn Courses",[23,1060,1061],{},"Look for the success message",[23,1063,1064],{},"Save the profile change",[268,1066,1067,1074],{"v-slot:right":270},[108,1068,1069],{},[334,1070],{"alt":1071,"src":1072,"variant":338,"max-height":1073},"Discord authorization prompt for Learn Courses","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-auth.png","25rem",[108,1075,1076],{},[334,1077],{"alt":1078,"src":1079,"variant":338,"max-height":1080},"Learn Courses success message after connecting Discord","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fdiscord-connected-success.png","7rem",[11,1082,1084,1087,1090,1096,1103],{"id":1083,"level":255},"join-the-channel",[16,1085,1086],{"id":1083},"Join The Channel",[108,1088,1089],{},"Use the Discord link provided on Canvas, or use:",[108,1091,1092],{},[86,1093,1094],{"href":1094,"rel":1095},"https:\u002F\u002Fdiscord.com\u002Finvite\u002FYEHcm44wzg",[90],[108,1097,1098,1099,1102],{},"This should send you to the ",[70,1100,1101],{},"access-channel"," channel.",[20,1104,1105,1108,1111],{},[23,1106,1107],{},"Other channels are protected by a bot",[23,1109,1110],{},"Messages may be blocked until your name and role are set",[23,1112,1113],{},"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,1115,1117,1120],{"id":1116,"level":14},"verify-with-quackbot",[16,1118,1119],{"id":1116},"Verify With QuackBot",[261,1121,1122,1167],{"gap":263,"left-width":483,"right-width":483},[268,1123,1124,1136,1142,1147,1150,1164],{"v-slot:left":270},[20,1125,1126,1129],{},[23,1127,1128],{},"A summer 2026 change was to have the bot attempt to auto-detect new members and apply roles automatically",[23,1130,1131,1132,1135],{},"If you don't see the proper semester category (i.e., ",[70,1133,1134],{},"summer-2026",") or the expected channels you can do the below action",[108,1137,1138,1139,1141],{},"In ",[70,1140,1101],{},", enter:",[108,1143,1144],{},[70,1145,1146],{},"@QuackBot",[108,1148,1149],{},"QuackBot will:",[20,1151,1152,1155,1158,1161],{},[23,1153,1154],{},"Verify your account",[23,1156,1157],{},"Pull in your name and section",[23,1159,1160],{},"Apply your class role",[23,1162,1163],{},"Update your server nickname",[108,1165,1166],{},"This does not change your real Discord username.",[268,1168,1169],{"v-slot:right":270},[108,1170,1171],{},[334,1172],{"alt":1173,"src":1174,"variant":338,"max-height":1175},"QuackBot response showing the student already has a course role","\u002Fimages\u002Finternet-applications\u002Flearn-courses-discord\u002Fquackbot-role-response.png","8rem",[11,1177,1179,1183,1186,1197,1201],{"id":1178,"level":14},"welcome-and-potential-issues",[16,1180,1182],{"id":1181},"welcome","Welcome",[108,1184,1185],{},"If the previous steps worked, you should see a new semester category in the Discord sidebar.",[20,1187,1188,1191,1194],{},[23,1189,1190],{},"It should appear after the general channels",[23,1192,1193],{},"It should include one or more channels for your active courses",[23,1195,1196],{},"Use the correct course channel for class questions and discussion",[179,1198,1200],{"id":1199},"potential-issues","Potential Issues",[20,1202,1203,1206],{},[23,1204,1205],{},"If you recently joined the class, your UCID may still need to be added to Learn Courses",[23,1207,1208,1209,1212],{},"If there is an issue, email the instructor or DM ",[70,1210,1211],{},"MattToegel",[20,1213,1214],{},[23,1215,1216],{},"Some Discord privacy settings may require a friend request before DMs work",[11,1218,1220,1223],{"id":1219,"level":14},"general-conduct",[16,1221,1222],{"id":1219},"General Conduct",[20,1224,1225,1228,1231,1242,1245,1253,1261,1264],{},[23,1226,1227],{},"Use class-related channels for questions and discussion",[23,1229,1230],{},"Ask general course questions in the channel instead of DM when possible",[23,1232,1233,1234],{},"Do not post screenshots of in-progress assignment solutions\n",[20,1235,1236,1239],{},[23,1237,1238],{},"This would be more ideal for a DM",[23,1240,1241],{},"If you see posted solution-like items don't assume they're correct",[23,1243,1244],{},"General unrelated code is okay when it supports a discussion (like content from a presentation or reading)",[23,1246,1247,1248],{},"If the instructor needs to see assignment code, they may ask you to DM the screenshot\n",[20,1249,1250],{},[23,1251,1252],{},"Since repositories should be set to private; repo links are fine to post in the class channel since other students should not have access to them",[23,1254,1255,1256],{},"Keep off-topic items out of class channels\n",[20,1257,1258],{},[23,1259,1260],{},"There are plenty of categorized channels to use and I can always make more",[23,1262,1263],{},"Helping classmates understand topics is encouraged just be mindful not to spoon-feed",[23,1265,1266],{},"Sharing direct solutions goes against the Academic Integrity Policy",[11,1268,1269,1271,1274],{"id":698,"level":14},[16,1270,701],{"id":698},[108,1272,1273],{},"Before continuing, confirm:",[20,1275,1276,1279,1282,1285,1288,1291],{},[23,1277,1278],{},"You can sign in to Learn Courses with your NJIT email",[23,1280,1281],{},"Your profile is saved",[23,1283,1284],{},"Discord is associated with your Learn Courses profile",[23,1286,1287],{},"You joined the Discord server",[23,1289,1290],{},"QuackBot applied your course role",[23,1292,1293],{},"You can see the correct course channel",[11,1295,1296,1298],{"id":781,"level":14},[16,1297,784],{"id":781},[20,1299,1300,1303,1311,1314,1317],{},[23,1301,1302],{},"Learn Courses supports course tools and course-specific setup",[23,1304,1305,1306],{},"Canvas remains the official assignment, grade, and course hub\n",[20,1307,1308],{},[23,1309,1310],{},"All necessary items will be linked on Canvas",[23,1312,1313],{},"Discord is the preferred quick communication channel",[23,1315,1316],{},"QuackBot connects your Discord account to the correct course role",[23,1318,1319],{},"Good course communication keeps help requests specific and protects private information",{"title":270,"searchDepth":424,"depth":424,"links":1321},[1322,1323,1324,1325,1326,1327,1328,1329,1332,1333,1334],{"id":870,"depth":424,"text":871},{"id":904,"depth":424,"text":862},{"id":941,"depth":424,"text":944},{"id":986,"depth":424,"text":989},{"id":1035,"depth":424,"text":1038},{"id":1083,"depth":424,"text":1086},{"id":1116,"depth":424,"text":1119},{"id":1181,"depth":424,"text":1182,"children":1330},[1331],{"id":1199,"depth":437,"text":1200},{"id":1219,"depth":424,"text":1222},{"id":698,"depth":424,"text":701},{"id":781,"depth":424,"text":784},"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.","20",{},"0","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",{"title":862,"description":1335},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F00-learn-courses-and-discord",[1344,1345,1346,1347],"course-tools","learn-courses","discord","setup","11:16","ScmHyEF1sA0","https:\u002F\u002Fyoutu.be\u002FScmHyEF1sA0","Joining Learn Platform and Discord Server","tEFV7lUabcy7whz7FSHEjPXSirrd3ginqQq4O4AkW9o",{"id":1354,"title":1355,"audience":6,"body":1356,"contentType":832,"course":158,"description":2400,"estimateBasis":2401,"estimatedDiscussionMinutes":835,"estimatedLiveMinutes":2402,"estimatedTotalMinutes":2403,"extension":838,"meta":2404,"module":840,"navigation":841,"order":835,"path":2405,"promptAssist":844,"seo":2406,"status":846,"stem":2407,"tags":2408,"videoDuration":2412,"videoId":2413,"videoLink":2414,"videoTitle":1355,"week":840,"__hash__":2415},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands.md","Basic CLI Commands",{"type":8,"value":1357,"toc":2366},[1358,1416,1450,1482,1544,1610,1661,1687,1704,1742,1770,1791,1826,1848,1920,1943,1988,2050,2102,2130,2150,2179,2217,2247,2257,2319],[11,1359,1361,1365],{"id":1360,"level":14},"why-cli-first",[16,1362,1364],{"id":1363},"why-cli-comes-first","Why CLI Comes First",[20,1366,1367,1375,1383,1397,1405],{},[23,1368,1369,1370],{},"Common language for setup and developer tools\n",[20,1371,1372],{},[23,1373,1374],{},"Git, servers, package installs, deployment logs",[23,1376,1377,1378],{},"Works when there is no full desktop\n",[20,1379,1380],{},[23,1381,1382],{},"SSH, Ubuntu Server, minimal system access",[23,1384,1385,1386],{},"Direct check of what the computer sees\n",[20,1387,1388,1391,1394],{},[23,1389,1390],{},"Current folder",[23,1392,1393],{},"Files and permissions",[23,1395,1396],{},"Command output",[23,1398,1399,1400],{},"Repeatable steps beat guessing through menus\n",[20,1401,1402],{},[23,1403,1404],{},"Run a command, read output, adjust",[23,1406,1407,1408],{},"Location still matters\n",[20,1409,1410,1413],{},[23,1411,1412],{},"Wrong folder can make correct commands fail",[23,1414,1415],{},"Or create files in the wrong place",[11,1417,1418,1420,1423],{"id":34,"level":14},[16,1419,37],{"id":34},[108,1421,1422],{},"Build the command-line habits that make setup work predictable:",[20,1424,1425,1428,1431,1444,1447],{},[23,1426,1427],{},"Know what folder the terminal is using",[23,1429,1430],{},"Read file and folder lists before moving",[23,1432,1433,1434,236,1437,1440,1441],{},"Recognize common flags like ",[70,1435,1436],{},"-a",[70,1438,1439],{},"-r",", and ",[70,1442,1443],{},"-l",[23,1445,1446],{},"Make small file changes and verify them",[23,1448,1449],{},"Stop safely when output does not match the lesson",[11,1451,1453,1456,1459,1479],{"id":1452,"level":14},"before-you-start",[16,1454,1455],{"id":1452},"Before You Start",[108,1457,1458],{},"Run these commands on your host computer",[20,1460,1461,1473,1476],{},[23,1462,1463,1464],{},"Windows: Git Bash",[20,1465,1466],{},[23,1467,1468,1469],{},"Need Git Bash now? Use the Windows install slide in the next presentation:\n",[86,1470,1472],{"href":1471},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fview\u002Fslides#step-1-install-git-on-windows","Install Git On Windows",[23,1474,1475],{},"Apple macOS: Terminal",[23,1477,1478],{},"Linux: Terminal",[108,1480,1481],{},"Use one terminal window for the whole practice so your location is easy to track",[11,1483,1485,1489],{"id":1484,"level":14},"working-directory",[16,1486,1488],{"id":1487},"the-main-idea","The Main Idea",[20,1490,1491,1502,1513,1536],{},[23,1492,1493,1494],{},"Terminal commands run from one folder at a time\n",[20,1495,1496],{},[23,1497,1498,1499],{},"That folder is the ",[963,1500,1501],{},"working directory",[23,1503,1504,1507,1508],{},[70,1505,1506],{},"pwd",": print working directory\n",[20,1509,1510],{},[23,1511,1512],{},"Shows the full path to the folder your terminal is using",[23,1514,1515,1516],{},"Fresh terminal usually starts in your home folder\n",[20,1517,1518,1524,1530],{},[23,1519,1520,1521],{},"Windows Git Bash: ",[70,1522,1523],{},"\u002Fc\u002FUsers\u002Fyour-username",[23,1525,1526,1527],{},"Apple macOS: ",[70,1528,1529],{},"\u002FUsers\u002Fyour-username",[23,1531,1532,1533],{},"Linux: ",[70,1534,1535],{},"\u002Fhome\u002Fyour-username",[23,1537,1538,1539],{},"Commands from this lesson start from the working directory\n",[20,1540,1541],{},[23,1542,1543],{},"Unless you give a different path",[11,1545,1547,1550,1553,1604],{"id":1546,"level":14},"paths-relative-and-absolute",[16,1548,1549],{"id":1546},"Paths: Relative And Absolute",[108,1551,1552],{},"Paths build on the working directory. They tell the terminal which file or folder you mean",[20,1554,1555,1561,1567,1573,1598],{},[23,1556,1557,1558],{},"Relative path: starts from the working directory, like ",[70,1559,1560],{},"public\u002Findex.php",[23,1562,1563,1564],{},"Absolute path: starts from the system root, like ",[70,1565,1566],{},"\u002Fhome\u002Fstudent\u002Fproject",[23,1568,1569,1572],{},[70,1570,1571],{},"."," means the current folder",[23,1574,1575,1578,1579],{},[70,1576,1577],{},".."," means the parent folder\n",[20,1580,1581,1587,1592],{},[23,1582,1583,1586],{},[70,1584,1585],{},"..\u002F.."," goes up two folders",[23,1588,502,1589],{},[70,1590,1591],{},"cd ..\u002F..",[23,1593,1594,1597],{},[70,1595,1596],{},"..."," is not a shortcut",[23,1599,1600,1603],{},[70,1601,1602],{},"~"," means your home folder",[108,1605,1606,1607,1609],{},"If a command affects the wrong place, check ",[70,1608,1506],{}," first, then check the path you typed",[11,1611,1613,1616,1619,1638,1641],{"id":1612,"level":14},"flags-options-and-arguments",[16,1614,1615],{"id":1612},"Flags, Options, And Arguments",[108,1617,1618],{},"Commands usually follow this shape:",[20,1620,1621,1627,1632],{},[23,1622,1623,1624],{},"Command: what to do, like ",[70,1625,1626],{},"ls",[23,1628,1629,1630],{},"Flag or option: how to do it, like ",[70,1631,1436],{},[23,1633,1634,1635],{},"Argument: what to do it to, like ",[70,1636,1637],{},"public_html",[108,1639,1640],{},"Examples:",[20,1642,1643,1649,1655],{},[23,1644,1645,1648],{},[70,1646,1647],{},"ls -a"," shows hidden files",[23,1650,1651,1654],{},[70,1652,1653],{},"cp -r folder backup-folder"," copies a folder",[23,1656,1657,1660],{},[70,1658,1659],{},"nano -l file.txt"," opens with line numbers",[11,1662,1664,1668,1671,1682],{"id":1663,"level":14},"practice-loop",[16,1665,1667],{"id":1666},"practice-1-location-and-paths","Practice 1: Location And Paths",[108,1669,1670],{},"For each command, use the same pattern:",[410,1672,1673,1676,1679],{},[23,1674,1675],{},"Run one command",[23,1677,1678],{},"Read the output",[23,1680,1681],{},"Confirm the folder or file changed the way you expected",[20,1683,1684],{},[23,1685,1686],{},"See the slides below for workflow steps, checkpoints, and expected results",[11,1688,1690,1693,1695,1698,1701],{"id":1689,"level":255},"step-1-confirm-where-you-are",[16,1691,1692],{"id":1689},"Step 1: Confirm Where You Are",[108,1694,631],{},[540,1696],{"language":542,"src":1697},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-confirm-where-you-01.sh",[108,1699,1700],{},"Expected result: a folder path",[108,1702,1703],{},"If you see a path, the terminal is working and you know your current location",[11,1705,1707,1710,1712,1715,1718,1721,1724],{"id":1706,"level":255},"step-2-list-files",[16,1708,1709],{"id":1706},"Step 2: List Files",[108,1711,631],{},[540,1713],{"language":542,"src":1714},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-02.sh",[108,1716,1717],{},"Expected result: file and folder names from your current location",[108,1719,1720],{},"For hidden files and details too, run:",[540,1722],{"language":542,"src":1723},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-list-files-03.sh",[20,1725,1726,1731,1736],{},[23,1727,1728,1730],{},[70,1729,1436],{}," includes hidden files",[23,1732,1733,1735],{},[70,1734,1443],{}," uses a long listing",[23,1737,1738,1741],{},[70,1739,1740],{},"-la"," combines both",[11,1743,1745,1748,1751,1754,1761,1767],{"id":1744,"level":255},"step-3-change-folders",[16,1746,1747],{"id":1744},"Step 3: Change Folders",[108,1749,1750],{},"Start from your home folder, then move up and back",[540,1752],{"language":542,"src":1753},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-3-change-folders-04.sh",[108,1755,1756,1757,1760],{},"This avoids assuming your computer has a specific folder like ",[70,1758,1759],{},"Documents"," in the current location",[108,1762,1763,1764,1766],{},"When you move into a named folder later, run ",[70,1765,1626],{}," first and pick a folder that actually appears in the list",[108,1768,1769],{},"If a path has spaces, wrap it in quotes",[11,1771,1773,1777,1779,1782],{"id":1772,"level":255},"step-4-create-practice-folder",[16,1774,1776],{"id":1775},"step-4-create-a-practice-folder","Step 4: Create A Practice Folder",[108,1778,631],{},[540,1780],{"language":542,"src":1781},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-4-create-a-practice-05.sh",[108,1783,1784,1785,1787,1788],{},"Expected result: ",[70,1786,1506],{}," ends with ",[70,1789,1790],{},"cli-practice",[11,1792,1794,1798,1800,1803,1806],{"id":1793,"level":255},"step-5-create-and-read-file",[16,1795,1797],{"id":1796},"step-5-write-text-to-a-file","Step 5: Write Text To A File",[108,1799,631],{},[540,1801],{"language":542,"src":1802},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-write-text-to-a-f-06.sh",[108,1804,1805],{},"What this command does:",[20,1807,1808,1814,1820],{},[23,1809,1810,1813],{},[70,1811,1812],{},"echo"," prepares text for the terminal",[23,1815,1816,1819],{},[70,1817,1818],{},">"," redirects that text into a file instead of printing it on screen",[23,1821,1822,1825],{},[70,1823,1824],{},"cli-proof.txt"," is created in the current folder, or replaced if it already exists",[11,1827,1829,1833,1836,1839,1845],{"id":1828,"level":255},"step-5-read-file-back",[179,1830,1832],{"id":1831},"step-5-continued-read-the-file-back","Step 5 Continued: Read The File Back",[108,1834,1835],{},"Then read it back:",[540,1837],{"language":542,"src":1838},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-5-continued-read-th-07.sh",[108,1840,1841,1844],{},[70,1842,1843],{},"cat"," prints file contents in the terminal",[108,1846,1847],{},"Expected result: the terminal prints the text you wrote",[11,1849,1851,1855,1857,1866,1869,1895,1898],{"id":1850,"level":14},"file-management-loop",[16,1852,1854],{"id":1853},"practice-2-file-management","Practice 2: File Management",[108,1856,1670],{},[410,1858,1859,1861,1863],{},[23,1860,1675],{},[23,1862,1678],{},[23,1864,1865],{},"Confirm the file changed the way you expected",[108,1867,1868],{},"Commands in this practice:",[20,1870,1871,1877,1883,1889],{},[23,1872,1873,1876],{},[70,1874,1875],{},"touch"," creates an empty file",[23,1878,1879,1882],{},[70,1880,1881],{},"cp"," copies a file or folder",[23,1884,1885,1888],{},[70,1886,1887],{},"mv"," moves or renames",[23,1890,1891,1894],{},[70,1892,1893],{},"rm"," deletes",[108,1896,1897],{},"Important flags:",[20,1899,1900,1906,1912,1918],{},[23,1901,1902,1905],{},[70,1903,1904],{},"cp -r"," copies folders",[23,1907,1908,1911],{},[70,1909,1910],{},"rm -r"," deletes folders",[23,1913,1914,1917],{},[70,1915,1916],{},"rm -f"," forces deletion",[23,1919,1686],{},[11,1921,1923,1927,1929,1932,1937],{"id":1922,"level":255},"practice-2-step-1-create-empty-file",[16,1924,1926],{"id":1925},"step-1-create-an-empty-file","Step 1: Create An Empty File",[108,1928,631],{},[540,1930],{"language":542,"src":1931},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-1-create-an-empty-f-08.sh",[108,1933,1934,1936],{},[70,1935,1875],{}," creates an empty file, or updates the timestamp if the file already exists",[108,1938,1784,1939,1942],{},[70,1940,1941],{},"practice-empty.txt"," appears in the folder list",[11,1944,1946,1950,1952,1955,1958,1964,1977],{"id":1945,"level":255},"practice-2-step-2-copy-rename-and-delete",[16,1947,1949],{"id":1948},"step-2-copy-rename-and-delete","Step 2: Copy, Rename, And Delete",[108,1951,631],{},[540,1953],{"language":542,"src":1954},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fstep-2-copy-rename-and-d-09.sh",[108,1956,1957],{},"Expected result: the backup is copied, renamed, then removed",[108,1959,1960,1961,1963],{},"Use ",[70,1962,1893],{}," carefully. Deleting from the terminal usually skips the recycle bin",[20,1965,1966,1971],{},[23,1967,1968,1970],{},[70,1969,1439],{},": recursive, includes folders and everything inside them",[23,1972,1973,1976],{},[70,1974,1975],{},"-f",": force, skips many confirmation prompts",[1978,1979,1981],"alert",{"color":1980},"red",[108,1982,1983,1984,1987],{},"Never run ",[70,1985,1986],{},"rm -rf \u002F",". It can try to delete the whole system from the root folder.",[11,1989,1991,1995,1998,2015,2020,2025,2045],{"id":1990,"level":14},"terminal-editors",[16,1992,1994],{"id":1993},"practice-3-terminal-editors","Practice 3: Terminal Editors",[108,1996,1997],{},"Sometimes you need to edit a file from a terminal",[20,1999,2000,2006],{},[23,2001,2002,2005],{},[70,2003,2004],{},"nano"," is beginner-friendly",[23,2007,2008,159,2011,2014],{},[70,2009,2010],{},"vi",[70,2012,2013],{},"vim"," is common on servers but has a learning curve",[108,2016,1960,2017,2019],{},[70,2018,2004],{}," for this course unless a lesson says otherwise",[108,2021,1960,2022,2024],{},[70,2023,1659],{}," when line numbers would help",[108,2026,2027,2028,159,2030,2032,2033,2036,2037,2040,2041,2044],{},"If you accidentally open ",[70,2029,2010],{},[70,2031,2013],{},", press ",[70,2034,2035],{},"Esc",", type ",[70,2038,2039],{},":q",", and press ",[70,2042,2043],{},"Enter"," to exit without saving",[20,2046,2047],{},[23,2048,2049],{},"See the slide below for workflow steps, checkpoints, and expected results",[11,2051,2053,2058,2060,2063,2068,2090],{"id":2052,"level":255},"edit-with-nano",[16,2054,2055,2056],{"id":2052},"Edit With ",[70,2057,2004],{},[108,2059,631],{},[540,2061],{"language":542,"src":2062},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fedit-with-nano-10.sh",[108,2064,1138,2065,2067],{},[70,2066,2004],{},":",[20,2069,2070,2073,2080,2084],{},[23,2071,2072],{},"Type a short note",[23,2074,2075,2076,2079],{},"Press ",[70,2077,2078],{},"Ctrl+O"," to save",[23,2081,2075,2082],{},[70,2083,2043],{},[23,2085,2075,2086,2089],{},[70,2087,2088],{},"Ctrl+X"," to exit",[108,2091,2092,2093,2095,2096,2036,2098,2040,2100],{},"If you open ",[70,2094,2010],{}," by mistake, press ",[70,2097,2035],{},[70,2099,2039],{},[70,2101,2043],{},[11,2103,2105,2111,2116,2119,2122,2125],{"id":2104,"level":14},"sudo-and-permission-boundaries",[16,2106,2107,2110],{"id":2104},[70,2108,2109],{},"sudo"," And Permission Boundaries",[108,2112,2113,2115],{},[70,2114,2109],{}," runs a command with elevated permissions",[108,2117,2118],{},"Use it only when a setup lesson explicitly says to use it",[108,2120,2121],{},"Example:",[540,2123],{"language":542,"src":2124},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fsudo-and-permission-boun-11.sh",[20,2126,2127],{},[23,2128,2129],{},"See the slide below for supporting examples and follow-up details",[11,2131,2133,2138,2144],{"id":2132,"level":255},"sudo-by-operating-system",[179,2134,2135,2137],{"id":2132},[70,2136,2109],{}," By Operating System",[108,2139,2140,2141,2143],{},"On Linux and macOS, ",[70,2142,2109],{}," is common for package installation and service management",[108,2145,2146,2147,2149],{},"Modern Windows also has a native ",[70,2148,2109],{}," 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,2151,2153,2156,2159,2170],{"id":2152,"level":14},"quick-safety-routine",[16,2154,2155],{"id":2152},"Quick Safety Routine",[108,2157,2158],{},"Before a command changes files, ask:",[20,2160,2161,2164,2167],{},[23,2162,2163],{},"What folder am I in?",[23,2165,2166],{},"Do I see the files I expect?",[23,2168,2169],{},"Am I about to change the right folder?",[108,2171,2172,2173,2175,2176],{},"If one answer is unclear, stop and run ",[70,2174,1506],{}," plus ",[70,2177,2178],{},"ls -la",[11,2180,2181,2183],{"id":678,"level":14},[16,2182,681],{"id":678},[20,2184,2185,2201,2207,2215],{},[23,2186,2187,2190,2191,2193,2194,2196,2197,2200],{},[70,2188,2189],{},"No such file or directory",": run ",[70,2192,1506],{},", then ",[70,2195,1626],{},", then try ",[70,2198,2199],{},"cd"," again",[23,2202,2203,2204,2206],{},"Command affected the wrong folder: check ",[70,2205,1506],{}," before continuing",[23,2208,2209,2211,2212,2214],{},[70,2210,1843],{}," cannot find the file: run ",[70,2213,2178],{}," and check the exact filename",[23,2216,2129],{},[11,2218,2220,2224],{"id":2219,"level":255},"common-mistakes-recovery",[179,2221,2223],{"id":2222},"recovery-checks","Recovery Checks",[20,2225,2226,2229,2235,2241],{},[23,2227,2228],{},"Spaces in a path: wrap the path in quotes",[23,2230,2231,2232],{},"Command keeps running: press ",[70,2233,2234],{},"Ctrl+C",[23,2236,2237,2238],{},"Permission denied: move back home with ",[70,2239,2240],{},"cd ~",[23,2242,2243,2244,2246],{},"Wrong ",[70,2245,1893],{},": stop and ask before doing more work",[11,2248,2249,2251,2254],{"id":698,"level":14},[16,2250,701],{"id":698},[108,2252,2253],{},"You are ready for the next setup lesson when these commands make sense:",[540,2255],{"language":542,"src":2256},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands\u002Fquick-check-12.sh",[11,2258,2259,2261],{"id":754,"level":14},[16,2260,727],{"id":724},[261,2262,2263,2292],{"gap":263,"left-width":483,"right-width":483},[268,2264,2265,2267,2273,2281],{"v-slot:left":270},[179,2266,735],{"id":734},[108,2268,2269,2272],{},[963,2270,2271],{},"Working directory"," - The folder where the next terminal command runs",[108,2274,2275,2277,2278],{},[963,2276,511],{}," - A file or folder location, such as ",[70,2279,2280],{},"public_html\u002Findex.php",[108,2282,2283,2286,2287,2289,2290],{},[963,2284,2285],{},"Flag"," - An extra command option, such as ",[70,2288,1740],{}," in ",[70,2291,2178],{},[268,2293,2294,2296],{"v-slot:right":270},[179,2295,755],{"id":754},[20,2297,2298,2305,2312],{},[23,2299,2300],{},[86,2301,2304],{"href":2302,"rel":2303},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fdesktop\u002Fen\u002Flatest\u002Ftutorial\u002Fthe-linux-command-line-for-beginners\u002F",[90],"Ubuntu Tutorial: The Linux Command Line For Beginners",[23,2306,2307],{},[86,2308,2311],{"href":2309,"rel":2310},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fcoreutils\u002Fmanual\u002Fcoreutils.html",[90],"GNU Coreutils Manual",[23,2313,2314],{},[86,2315,2318],{"href":2316,"rel":2317},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn_web_development\u002FGetting_started\u002FEnvironment_setup\u002FCommand_line",[90],"MDN: Command Line Crash Course",[11,2320,2321,2323,2326],{"id":781,"level":14},[16,2322,784],{"id":781},[108,2324,2325],{},"Before leaving this presentation, confirm you can:",[20,2327,2328,2333,2338,2349,2363],{},[23,2329,1960,2330,2332],{},[70,2331,1506],{}," to check where commands will run",[23,2334,1960,2335,2337],{},[70,2336,2178],{}," to inspect the current folder",[23,2339,1960,2340,236,2342,236,2344,1440,2346,2348],{},[70,2341,2199],{},[70,2343,1571],{},[70,2345,1577],{},[70,2347,1602],{}," to move intentionally",[23,2350,2351,2352,236,2354,236,2356,236,2358,1440,2360,2362],{},"Use file commands such as ",[70,2353,1875],{},[70,2355,1881],{},[70,2357,1887],{},[70,2359,1893],{},[70,2361,2004],{}," carefully",[23,2364,2365],{},"Stop and check location when output does not match the lesson",{"title":270,"searchDepth":424,"depth":424,"links":2367},[2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2382,2383,2384,2385,2386,2388,2393,2394,2397,2398,2399],{"id":1363,"depth":424,"text":1364},{"id":34,"depth":424,"text":37},{"id":1452,"depth":424,"text":1455},{"id":1487,"depth":424,"text":1488},{"id":1546,"depth":424,"text":1549},{"id":1612,"depth":424,"text":1615},{"id":1666,"depth":424,"text":1667},{"id":1689,"depth":424,"text":1692},{"id":1706,"depth":424,"text":1709},{"id":1744,"depth":424,"text":1747},{"id":1775,"depth":424,"text":1776},{"id":1796,"depth":424,"text":1797,"children":2380},[2381],{"id":1831,"depth":437,"text":1832},{"id":1853,"depth":424,"text":1854},{"id":1925,"depth":424,"text":1926},{"id":1948,"depth":424,"text":1949},{"id":1993,"depth":424,"text":1994},{"id":2052,"depth":424,"text":2387},"Edit With nano",{"id":2104,"depth":424,"text":2389,"children":2390},"sudo And Permission Boundaries",[2391],{"id":2132,"depth":437,"text":2392},"sudo By Operating System",{"id":2152,"depth":424,"text":2155},{"id":678,"depth":424,"text":681,"children":2395},[2396],{"id":2222,"depth":437,"text":2223},{"id":698,"depth":424,"text":701},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"Practice the terminal commands you need so you can move through folders, inspect files, and verify your location before running course commands.","Face-to-face class of about 40 students; includes short CLI demo, student command practice, path\u002Fflag checks, and common beginner recovery questions.","45","55",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",{"title":1355,"description":2400},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F01-basic-cli-commands",[2409,2410,2411],"cli","terminal","filesystem","46:05","NsSRKv_uBWM","https:\u002F\u002Fyoutu.be\u002FNsSRKv_uBWM","q_NRWUOCcsk5lm6u6kKPFGl9E9VqeQhaC0qb86nD7aY",{"id":2417,"title":2418,"audience":6,"body":2419,"contentType":832,"course":158,"description":3288,"estimateBasis":3289,"estimatedDiscussionMinutes":835,"estimatedLiveMinutes":3290,"estimatedTotalMinutes":2402,"extension":838,"meta":3291,"module":840,"navigation":841,"order":1337,"path":3292,"promptAssist":844,"seo":3293,"status":846,"stem":3294,"tags":3295,"videoDuration":3296,"videoId":3297,"videoLink":3298,"videoTitle":2418,"week":840,"__hash__":3299},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools.md","Git Tools",{"type":8,"value":2420,"toc":3258},[2421,2444,2473,2500,2537,2568,2600,2635,2664,2694,2731,2734,2764,2795,2824,2874,2892,2909,2929,2954,2985,3003,3044,3088,3169,3229],[11,2422,2423,2425],{"id":34,"level":14},[16,2424,37],{"id":34},[20,2426,2427,2430,2433],{},[23,2428,2429],{},"Install Git",[23,2431,2432],{},"Choose one terminal for your operating system",[23,2434,2435,2436,236,2439,1440,2441,2443],{},"Confirm ",[70,2437,2438],{},"git --version",[70,2440,1506],{},[70,2442,2178],{}," work before GitHub setup",[11,2445,2447,2451],{"id":2446,"level":14},"terminal-choice-by-os",[16,2448,2450],{"id":2449},"terminal-choices","Terminal Choices",[20,2452,2453,2456,2459,2462,2464,2467,2470],{},[23,2454,2455],{},"Pick the terminal for your operating system",[23,2457,2458],{},"Use that same terminal for this lesson path",[23,2460,2461],{},"Run commands on your own computer unless a later lesson explicitly says \"inside the VM\"",[23,2463,1463],{},[23,2465,2466],{},"Apple macOS: Terminal, with iTerm2 optional",[23,2468,2469],{},"Linux: Terminal, with Tilix optional",[23,2471,2472],{},"These operating system notes are alternatives, not a sequence",[11,2474,2476,2480,2497],{"id":2475,"level":14},"step-1-install-git-on-windows",[16,2477,2479],{"id":2478},"windows-path-git-bash","Windows Path: Git Bash",[410,2481,2482,2488,2491,2494],{},[23,2483,360,2484],{},[86,2485,2486],{"href":2486,"rel":2487},"https:\u002F\u002Fgit-scm.com\u002Finstall\u002Fwindows",[90],[23,2489,2490],{},"Download and run the Git for Windows installer",[23,2492,2493],{},"Open Git Bash from the Start menu",[23,2495,2496],{},"Use Git Bash whenever this course says to use the terminal",[108,2498,2499],{},"See the slides below for the install settings, launch check, and Windows terminal habit",[11,2501,2503,2506],{"id":2502,"level":255},"windows-installer-components",[179,2504,2505],{"id":2502},"Windows Installer: Components",[261,2507,2510,2518],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},"1.4fr","never",[268,2511,2512],{"v-slot:left":270},[108,2513,2514],{},[334,2515],{"alt":2516,"src":2517,"variant":338},"Git for Windows installer component selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep01_components.png",[268,2519,2520],{"v-slot:right":270},[20,2521,2522,2525,2531],{},[23,2523,2524],{},"Recommended to have these components selected",[23,2526,2527,2528],{},"Keep ",[70,2529,2530],{},"Git Bash Here",[23,2532,2533,2534],{},"Continue with ",[70,2535,2536],{},"Next",[11,2538,2540,2543],{"id":2539,"level":255},"windows-installer-default-editor",[179,2541,2542],{"id":2539},"Windows Installer: Default Editor",[261,2544,2545,2553],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2546,2547],{"v-slot:left":270},[108,2548,2549],{},[334,2550],{"alt":2551,"src":2552,"variant":338},"Git for Windows installer default editor selection screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep02_default_editor.png",[268,2554,2555],{"v-slot:right":270},[20,2556,2557,2560,2565],{},[23,2558,2559],{},"Choose the editor you are comfortable with",[23,2561,2562,2564],{},[70,2563,2004],{}," or VS Code is friendlier than Vim for most beginners",[23,2566,2567],{},"This setting affects Git messages if Git opens an editor",[11,2569,2571,2574],{"id":2570,"level":255},"windows-installer-branch-name",[179,2572,2573],{"id":2570},"Windows Installer: Branch Name",[261,2575,2576,2584],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2577,2578],{"v-slot:left":270},[108,2579,2580],{},[334,2581],{"alt":2582,"src":2583,"variant":338},"Git for Windows installer default branch name screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep03_branch_naming.png",[268,2585,2586],{"v-slot:right":270},[20,2587,2588,2594,2597],{},[23,2589,2590,2591],{},"Select the option that uses ",[70,2592,2593],{},"main",[23,2595,2596],{},"Course repositories will tell you which branch to use later",[23,2598,2599],{},"Do not create custom branch names here",[11,2601,2603,2606],{"id":2602,"level":255},"windows-installer-path",[179,2604,2605],{"id":2602},"Windows Installer: PATH",[261,2607,2608,2616],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2609,2610],{"v-slot:left":270},[108,2611,2612],{},[334,2613],{"alt":2614,"src":2615,"variant":338},"Git for Windows installer PATH environment screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep04_path.png",[268,2617,2618],{"v-slot:right":270},[20,2619,2620,2623,2629,2632],{},[23,2621,2622],{},"Select the recommended PATH option",[23,2624,2625,2626],{},"This lets Git Bash and common tools find ",[70,2627,2628],{},"git",[23,2630,2631],{},"Avoid options that say Git Bash only",[23,2633,2634],{},"The third option can be used if you understand the consequences",[11,2636,2638,2641],{"id":2637,"level":255},"windows-installer-ssh",[179,2639,2640],{"id":2637},"Windows Installer: SSH",[261,2642,2643,2651],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2644,2645],{"v-slot:left":270},[108,2646,2647],{},[334,2648],{"alt":2649,"src":2650,"variant":338},"Git for Windows installer SSH executable screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep05_ssh_bundled.png",[268,2652,2653],{"v-slot:right":270},[20,2654,2655,2658,2661],{},[23,2656,2657],{},"Use the bundled OpenSSH option",[23,2659,2660],{},"This keeps Git Bash SSH behavior predictable",[23,2662,2663],{},"SSH setup happens in the next lesson",[11,2665,2667,2671],{"id":2666,"level":255},"windows-installer-openssl",[179,2668,2670],{"id":2669},"windows-installer-https","Windows Installer: HTTPS",[261,2672,2673,2681],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2674,2675],{"v-slot:left":270},[108,2676,2677],{},[334,2678],{"alt":2679,"src":2680,"variant":338},"Git for Windows installer HTTPS transport backend screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep06_openssl.png",[268,2682,2683],{"v-slot:right":270},[20,2684,2685,2688,2691],{},[23,2686,2687],{},"Keep the OpenSSL option",[23,2689,2690],{},"This is the normal Git for Windows choice",[23,2692,2693],{},"It supports secure GitHub connections",[11,2695,2697,2701],{"id":2696,"level":255},"windows-installer-checkout-style",[179,2698,2700],{"id":2699},"windows-installer-line-endings","Windows Installer: Line Endings",[261,2702,2703,2711],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2704,2705],{"v-slot:left":270},[108,2706,2707],{},[334,2708],{"alt":2709,"src":2710,"variant":338},"Git for Windows installer line ending conversion screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep07_checkout_style.png",[268,2712,2713,2724],{"v-slot:right":270},[20,2714,2715,2718,2721],{},[23,2716,2717],{},"Keep the default line-ending option",[23,2719,2720],{},"Git handles Windows and Linux line endings for you",[23,2722,2723],{},"Do not change this unless a lesson says to",[2725,2726,2728],"admonition",{"type":2727},"note",[108,2729,2730],{},"Line-ending warnings may appear later. They are usually informational, not a sign that there's an issue.",[108,2732,2733],{},"::\n::",[11,2735,2737,2741],{"id":2736,"level":255},"windows-installer-mintty",[179,2738,2740],{"id":2739},"windows-installer-terminal-emulator","Windows Installer: Terminal Emulator",[261,2742,2743,2751],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2744,2745],{"v-slot:left":270},[108,2746,2747],{},[334,2748],{"alt":2749,"src":2750,"variant":338},"Git for Windows installer terminal emulator screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep08_mintty.png",[268,2752,2753],{"v-slot:right":270},[20,2754,2755,2758,2761],{},[23,2756,2757],{},"Keep MinTTY selected",[23,2759,2760],{},"This is the normal Git Bash window",[23,2762,2763],{},"Course screenshots will assume this terminal style",[11,2765,2767,2771],{"id":2766,"level":255},"windows-installer-fast-forward",[179,2768,2770],{"id":2769},"windows-installer-pull-behavior","Windows Installer: Pull Behavior",[261,2772,2773,2781],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2774,2775],{"v-slot:left":270},[108,2776,2777],{},[334,2778],{"alt":2779,"src":2780,"variant":338},"Git for Windows installer git pull behavior screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep09_ff_merge.png",[268,2782,2783],{"v-slot:right":270},[20,2784,2785,2792],{},[23,2786,2787,2788,2791],{},"Keep the default ",[70,2789,2790],{},"git pull"," behavior",[23,2793,2794],{},"Later lessons explain pull, merge, and conflicts",[11,2796,2798,2801],{"id":2797,"level":255},"windows-installer-credential-manager",[179,2799,2800],{"id":2797},"Windows Installer: Credential Manager",[261,2802,2803,2811],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2804,2805],{"v-slot:left":270},[108,2806,2807],{},[334,2808],{"alt":2809,"src":2810,"variant":338},"Git for Windows installer credential manager screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep10_credential_manager.png",[268,2812,2813],{"v-slot:right":270},[20,2814,2815,2818,2821],{},[23,2816,2817],{},"Keep Git Credential Manager enabled",[23,2819,2820],{},"It helps with browser-based GitHub sign-in",[23,2822,2823],{},"This course still uses SSH for repo pushes",[11,2825,2827,2830],{"id":2826,"level":255},"windows-installer-extra-options",[179,2828,2829],{"id":2826},"Windows Installer: Extra Options",[261,2831,2832,2840],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,2833,2834],{"v-slot:left":270},[108,2835,2836],{},[334,2837],{"alt":2838,"src":2839,"variant":338},"Git for Windows installer extra options screen","\u002Fimages\u002Finternet-applications\u002Fgitbash\u002Fstep11_extra_options_optional.png",[268,2841,2842],{"v-slot:right":270},[20,2843,2844,2852,2863,2871],{},[23,2845,2846,2847],{},"Enable file system caching\n",[20,2848,2849],{},[23,2850,2851],{},"Improves Git performance on Windows",[23,2853,2854,2855],{},"Enable symbolic links if available\n",[20,2856,2857,2860],{},[23,2858,2859],{},"Helps Git handle link-like files correctly",[23,2861,2862],{},"May require Windows Developer Mode or admin rights",[23,2864,2865,2866],{},"Skip experimental options\n",[20,2867,2868],{},[23,2869,2870],{},"They can change behavior between Git versions",[23,2872,2873],{},"Finish the installer",[11,2875,2877,2881],{"id":2876,"level":255},"step-1-open-git-bash-on-windows",[179,2878,2880],{"id":2879},"open-git-bash","Open Git Bash",[20,2882,2883,2886,2889],{},[23,2884,2885],{},"Start menu -> Git Bash",[23,2887,2888],{},"Pin it if that helps you find the same terminal later",[23,2890,2891],{},"Run the checks in the next slides from Git Bash",[11,2893,2895,2898],{"id":2894,"level":255},"windows-terminal-habit",[179,2896,2897],{"id":2894},"Windows Terminal Habit",[20,2899,2900,2903,2906],{},[23,2901,2902],{},"Use Git Bash for course commands on Windows",[23,2904,2905],{},"If another terminal opens by accident, close it and open Git Bash",[23,2907,2908],{},"Staying in one terminal makes setup problems easier to diagnose",[11,2910,2912,2915],{"id":2911,"level":14},"macos-path-terminal",[16,2913,2914],{"id":2911},"macOS Path: Terminal",[20,2916,2917,2920,2923,2926],{},[23,2918,2919],{},"Built-in Terminal is fully supported",[23,2921,2922],{},"Optional iTerm2 gives you tabs, split panes, and profiles",[23,2924,2925],{},"Beginner default: start with Terminal unless you already prefer iTerm2",[23,2927,2928],{},"See the slide below for the optional modern terminal install path",[11,2930,2932,2936],{"id":2931,"level":255},"macos-optional-iterm2-install",[179,2933,2935],{"id":2934},"optional-iterm2-install","Optional iTerm2 Install",[20,2937,2938,2945,2948,2951],{},[23,2939,2940,2941],{},"Download the stable release from ",[86,2942,2943],{"href":2943,"rel":2944},"https:\u002F\u002Fiterm2.com\u002Fdownloads.html",[90],[23,2946,2947],{},"Move iTerm2 to Applications",[23,2949,2950],{},"Open iTerm2 and run the same checks as Terminal",[23,2952,2953],{},"Use Terminal or iTerm2 consistently for course commands",[11,2955,2957,2960,2974,2977,2980],{"id":2956,"level":14},"linux-path-terminal",[16,2958,2959],{"id":2956},"Linux Path: Terminal",[20,2961,2962,2965,2968],{},[23,2963,2964],{},"Open the built-in Terminal app",[23,2966,2967],{},"Git is often installed already",[23,2969,2970,2971,2973],{},"If ",[70,2972,2438],{}," fails, use your distribution package manager",[108,2975,2976],{},"For Ubuntu:",[540,2978],{"language":542,"src":2979},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Flinux-path-terminal-01.sh",[20,2981,2982],{},[23,2983,2984],{},"See the slide below for the optional split-pane terminal setup",[11,2986,2988,2992,2995,2997,3000],{"id":2987,"level":255},"linux-optional-tilix-install",[179,2989,2991],{"id":2990},"optional-tilix-install","Optional Tilix Install",[108,2993,2994],{},"Tilix is a Linux terminal with split panes and profiles",[108,2996,2976],{},[540,2998],{"language":542,"src":2999},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Foptional-tilix-install-02.sh",[108,3001,3002],{},"Use the built-in Terminal if optional installs add friction",[11,3004,3006,3010],{"id":3005,"level":14},"step-3-confirm-git-and-shell",[16,3007,3009],{"id":3008},"confirm-git-and-shell","Confirm Git And Shell",[261,3011,3014,3028],{"gap":263,"left-width":3012,"right-width":3013},"1.15fr","0.85fr",[268,3015,3016,3018,3021,3024],{"v-slot:left":270},[108,3017,631],{},[540,3019],{"language":542,"src":3020},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fconfirm-git-and-shell-03.sh",[108,3022,3023],{},"Expected output:",[540,3025],{"language":3026,"src":3027},"plaintext","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-04.txt",[268,3029,3030,3033],{"v-slot:right":270},[108,3031,3032],{},"This confirms:",[20,3034,3035,3038,3041],{},[23,3036,3037],{},"Git is installed",[23,3039,3040],{},"The terminal can find Git",[23,3042,3043],{},"Your shell matches later course commands",[11,3045,3047,3051],{"id":3046,"level":14},"step-4-cli-safety-check-before-every-git-command",[16,3048,3050],{"id":3049},"check-location-before-git-commands","Check Location Before Git Commands",[261,3052,3053,3065],{"gap":263,"left-width":265,"right-width":264},[268,3054,3055,3057,3060,3062],{"v-slot:left":270},[108,3056,631],{},[540,3058],{"language":542,"src":3059},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fcheck-location-before-git-commands-05.sh",[108,3061,3023],{},[540,3063],{"language":3026,"src":3064},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools\u002Fexample-output-06.txt",[268,3066,3067,3070],{"v-slot:right":270},[108,3068,3069],{},"Use this before Git commands:",[20,3071,3072,3077,3082,3085],{},[23,3073,3074,3076],{},[70,3075,1506],{}," shows the current folder",[23,3078,3079,3081],{},[70,3080,2178],{}," shows what is inside it",[23,3083,3084],{},"If the folder is wrong, fix location first",[23,3086,3087],{},"Do not run Git commands while guessing",[11,3089,3090,3092],{"id":678,"level":14},[16,3091,681],{"id":678},[261,3093,3094,3136],{"gap":263,"left-width":483,"right-width":483},[268,3095,3096],{"v-slot:left":270},[20,3097,3098,3111,3128],{},[23,3099,3100,3103],{},[70,3101,3102],{},"git: command not found",[20,3104,3105,3108],{},[23,3106,3107],{},"Git is missing, or this terminal cannot find it",[23,3109,3110],{},"Close the terminal and reopen the correct one",[23,3112,3113,3116],{},[70,3114,3115],{},"not a git repository",[20,3117,3118,3121],{},[23,3119,3120],{},"The command ran outside a cloned repository",[23,3122,1960,3123,322,3125,3127],{},[70,3124,1506],{},[70,3126,2178],{},", then move to the repo folder",[23,3129,3130,3131],{},"Wrong terminal",[20,3132,3133],{},[23,3134,3135],{},"Windows users should switch back to Git Bash",[268,3137,3138,3141],{"v-slot:right":270},[23,3139,3140],{},"Too many terminals open",[410,3142,3143,3146,3156,3160,3166],{},[23,3144,3145],{},"Close extra terminal windows",[23,3147,3148,3149],{},"Open the correct terminal\n",[20,3150,3151,3153],{},[23,3152,1463],{},[23,3154,3155],{},"Apple macOS\u002FLinux: Terminal",[23,3157,397,3158],{},[70,3159,2438],{},[23,3161,397,3162,322,3164],{},[70,3163,1506],{},[70,3165,2178],{},[23,3167,3168],{},"Continue only after the folder looks right",[11,3170,3171,3173],{"id":754,"level":14},[16,3172,727],{"id":724},[261,3174,3175,3197],{"gap":263,"left-width":483,"right-width":483},[268,3176,3177,3179,3185,3191],{"v-slot:left":270},[179,3178,735],{"id":734},[108,3180,3181,3184],{},[963,3182,3183],{},"Terminal"," - A text-based interface where you type commands to control your computer",[108,3186,3187,3190],{},[963,3188,3189],{},"CLI (Command Line Interface)"," - The text-based interface where you type commands",[108,3192,3193,3196],{},[963,3194,3195],{},"Git"," - A tool for tracking changes in code files over time",[268,3198,3199,3201],{"v-slot:right":270},[179,3200,755],{"id":754},[20,3202,3203,3210,3216,3222],{},[23,3204,3205],{},[86,3206,3209],{"href":3207,"rel":3208},"https:\u002F\u002Fgit-scm.com\u002Fdownloads",[90],"Git Downloads",[23,3211,3212],{},[86,3213,3215],{"href":2486,"rel":3214},[90],"Git For Windows Install Page",[23,3217,3218],{},[86,3219,3221],{"href":2943,"rel":3220},[90],"iTerm2 Downloads",[23,3223,3224],{},[86,3225,3228],{"href":3226,"rel":3227},"https:\u002F\u002Fgnunn1.github.io\u002Ftilix-web\u002F",[90],"Tilix",[11,3230,3231,3233,3236],{"id":781,"level":14},[16,3232,784],{"id":781},[108,3234,3235],{},"Before moving on, confirm you can:",[20,3237,3238,3241,3245,3252,3255],{},[23,3239,3240],{},"Open the correct terminal for your operating system",[23,3242,397,3243],{},[70,3244,2438],{},[23,3246,1960,3247,322,3249,3251],{},[70,3248,1506],{},[70,3250,2178],{}," to check your location",[23,3253,3254],{},"Understand what terminal\u002FCLI refers to",[23,3256,3257],{},"Keep track of terminal instances",{"title":270,"searchDepth":424,"depth":424,"links":3259},[3260,3261,3262,3277,3280,3283,3284,3285,3286,3287],{"id":34,"depth":424,"text":37},{"id":2449,"depth":424,"text":2450},{"id":2478,"depth":424,"text":2479,"children":3263},[3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276],{"id":2502,"depth":437,"text":2505},{"id":2539,"depth":437,"text":2542},{"id":2570,"depth":437,"text":2573},{"id":2602,"depth":437,"text":2605},{"id":2637,"depth":437,"text":2640},{"id":2669,"depth":437,"text":2670},{"id":2699,"depth":437,"text":2700},{"id":2739,"depth":437,"text":2740},{"id":2769,"depth":437,"text":2770},{"id":2797,"depth":437,"text":2800},{"id":2826,"depth":437,"text":2829},{"id":2879,"depth":437,"text":2880},{"id":2894,"depth":437,"text":2897},{"id":2911,"depth":424,"text":2914,"children":3278},[3279],{"id":2934,"depth":437,"text":2935},{"id":2956,"depth":424,"text":2959,"children":3281},[3282],{"id":2990,"depth":437,"text":2991},{"id":3008,"depth":424,"text":3009},{"id":3049,"depth":424,"text":3050},{"id":678,"depth":424,"text":681},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"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":2418,"description":3288},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F02-install-git-tools",[2628,2410,1347],"21:30","u1x5bq-JmCg","https:\u002F\u002Fyoutu.be\u002Fu1x5bq-JmCg","71DrP8YI_ks4jUswWJXy9rmZOVVoeaJAEPancHNHsV4",{"id":3301,"title":3302,"audience":6,"body":3303,"contentType":832,"course":158,"description":4375,"estimateBasis":4376,"estimatedDiscussionMinutes":4377,"estimatedLiveMinutes":4378,"estimatedTotalMinutes":4379,"extension":838,"meta":4380,"module":840,"navigation":841,"order":836,"path":4381,"promptAssist":844,"seo":4382,"status":846,"stem":4383,"tags":4384,"videoDuration":4388,"videoId":4389,"videoLink":4390,"videoTitle":4391,"week":840,"__hash__":4392},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh.md","Set Up GitHub SSH",{"type":8,"value":3304,"toc":4347},[3305,3331,3349,3374,3387,3414,3451,3526,3573,3640,3716,3758,3784,3816,3854,3899,3933,4002,4004,4007,4018,4090,4119,4153,4201,4247,4315],[11,3306,3308,3311],{"id":3307,"level":14},"goals",[16,3309,3310],{"id":3307},"Goals",[20,3312,3313,3316,3319,3322,3325,3328],{},[23,3314,3315],{},"Confirm Git works in the correct terminal",[23,3317,3318],{},"Sign in to GitHub with a school or personal account",[23,3320,3321],{},"Create or reuse an SSH key for GitHub",[23,3323,3324],{},"Add the public key to GitHub",[23,3326,3327],{},"Create and clone your course repository",[23,3329,3330],{},"Set Git identity inside the cloned repository",[11,3332,3334,3337,3346],{"id":3333,"level":14},"terminal-by-os",[16,3335,3336],{"id":3333},"Terminal By OS",[20,3338,3339,3341,3344],{},[23,3340,1463],{},[23,3342,3343],{},"Apple macOS: Terminal or iTerm2",[23,3345,1478],{},[108,3347,3348],{},"Run these commands on your own computer",[11,3350,3352,3355],{"id":3351,"level":14},"git-and-ssh-terms",[16,3353,3354],{"id":3351},"Git And SSH Terms",[20,3356,3357,3360,3368,3371],{},[23,3358,3359],{},"Git identity: name and email attached to commits in a repository",[23,3361,3362,3363],{},"SSH key pair: private key stays on your computer, public key goes to GitHub\n",[20,3364,3365],{},[23,3366,3367],{},"This is how we'll authenticate to GitHub",[23,3369,3370],{},"SSH agent: helper that keeps your private key available to Git commands",[23,3372,3373],{},"Clone: local folder connected to a GitHub repository",[11,3375,3377,3380,3384],{"id":3376,"level":14},"ssh-key-flow",[16,3378,3379],{"id":3376},"SSH Key Flow",[3381,3382],"mermaid",{"code":3383},"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",[108,3385,3386],{},"GitHub receives only the public key. The private key stays on your computer",[11,3388,3390,3393],{"id":3389,"level":14},"step-1-check-git",[16,3391,3392],{"id":3389},"Step 1: Check Git",[261,3394,3395,3403],{"gap":263,"left-width":483,"right-width":483},[268,3396,3397,3399],{"v-slot:left":270},[108,3398,631],{},[540,3400],{"label":3401,"language":542,"src":3402},"check-git.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fstep-1-check-git-01.sh",[268,3404,3405,3407,3411],{"v-slot:right":270},[108,3406,3023],{},[540,3408],{"label":3409,"language":3026,"src":3410},"example-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-02.txt",[108,3412,3413],{},"A valid version means Git is installed and available in this terminal",[11,3415,3417,3421],{"id":3416,"level":14},"step-2-github-account",[16,3418,3420],{"id":3419},"step-2-sign-in-to-github","Step 2: Sign In To GitHub",[261,3422,3424,3443],{"gap":263,"left-width":483,"right-width":3423},"0.8fr",[268,3425,3426],{"v-slot:left":270},[20,3427,3428,3431,3434,3437,3440],{},[23,3429,3430],{},"Use an existing GitHub account or create one",[23,3432,3433],{},"School email recommended for course identity",[23,3435,3436],{},"Personal email is fine if you prefer it",[23,3438,3439],{},"Avoid work email so course access does not depend on an employer account",[23,3441,3442],{},"Confirm you can open GitHub Settings before continuing",[268,3444,3445],{"v-slot:right":270},[108,3446,3447],{},[334,3448],{"alt":3449,"src":3450,"variant":338},"GitHub account menu open with Settings visible","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-logged-in.png",[11,3452,3454,3458],{"id":3453,"level":14},"step-2-create-repo",[16,3455,3457],{"id":3456},"step-3-create-course-repository","Step 3: Create Course Repository",[261,3459,3460,3518],{"gap":263,"left-width":348,"right-width":3012},[268,3461,3462,3465],{"v-slot:left":270},[108,3463,3464],{},"In GitHub:",[20,3466,3467,3472,3478,3483,3498,3504,3507,3515],{},[23,3468,1004,3469],{},[70,3470,3471],{},"+",[23,3473,3474,3475],{},"Choose ",[70,3476,3477],{},"New repository",[23,3479,3480,3481],{},"Name it ",[70,3482,131],{},[23,3484,3485,3486,3489,3490,3493,3494,3497],{},"Semester code examples: ",[70,3487,3488],{},"S2026"," spring, ",[70,3491,3492],{},"M2026"," summer, ",[70,3495,3496],{},"F2026"," fall",[23,3499,3500,3501],{},"Set visibility to ",[70,3502,3503],{},"Private",[23,3505,3506],{},"Toggle \"Add README\"",[23,3508,3509,3510],{},"Do not toggle \"Add .gitignore\"",[20,3511,3512],{},[23,3513,3514],{},"A future lesson will discuss and add this important file",[23,3516,3517],{},"Do not add starter files unless instructed",[268,3519,3520],{"v-slot:right":270},[108,3521,3522],{},[334,3523],{"alt":3524,"src":3525,"variant":338},"GitHub new repository form with course naming pattern, private visibility, and README enabled","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fnew-repo.png",[11,3527,3529,3533,3559],{"id":3528,"level":14},"step-3-check-existing-key",[16,3530,3532],{"id":3531},"step-4-check-for-existing-ssh-key","Step 4: Check For Existing SSH Key",[261,3534,3535,3543],{"gap":263,"left-width":483,"right-width":483},[268,3536,3537,3539],{"v-slot:left":270},[108,3538,631],{},[540,3540],{"label":3541,"language":542,"src":3542},"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",[268,3544,3545,3547,3550],{"v-slot:right":270},[108,3546,660],{},[540,3548],{"label":3409,"language":3026,"src":3549},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-04.txt",[108,3551,3552,3553,322,3556],{},"Look for a matching GitHub-specific pair such as ",[70,3554,3555],{},"github_key",[70,3557,3558],{},"github_key.pub",[108,3560,3561,3562,3565,3566,159,3569,3572],{},"You can reuse an existing matching pair only if it is ",[963,3563,3564],{},"NOT"," a default key such as ",[70,3567,3568],{},"id_ed25519",[70,3570,3571],{},"id_rsa",". Otherwise, create a GitHub-specific key in the next step",[11,3574,3576,3580,3582,3586,3588,3591],{"id":3575,"level":14},"step-4-create-key-if-needed",[16,3577,3579],{"id":3578},"step-5-create-ssh-key-if-needed","Step 5: Create SSH Key If Needed",[108,3581,631],{},[540,3583],{"label":3584,"language":542,"src":3585},"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",[108,3587,660],{},[540,3589],{"label":3409,"language":3026,"src":3590},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-06.txt",[20,3592,3593,3619,3624,3629],{},[23,3594,3595,3596],{},"Command flags:\n",[20,3597,3598,3604,3610],{},[23,3599,3600,3603],{},[70,3601,3602],{},"-t"," chooses the key type",[23,3605,3606,3609],{},[70,3607,3608],{},"-C"," adds a comment label, usually your GitHub email",[23,3611,3612,3614,3615,3618],{},[70,3613,1975],{}," chooses the output file path (must include ",[70,3616,3617],{},"~\u002F.ssh\u002F"," followed by the file name)",[23,3620,3621,3623],{},[70,3622,3555],{}," is the private key file",[23,3625,3626,3628],{},[70,3627,3558],{}," is the public key file for GitHub",[23,3630,3631,3632],{},"Passphrase is optional unless your instructor requires one\n",[20,3633,3634,3637],{},[23,3635,3636],{},"Pro: protects the key if someone gets the file",[23,3638,3639],{},"Con: adds an unlock prompt when the key is used",[11,3641,3643,3647,3664,3696],{"id":3642,"level":14},"step-5-start-agent-and-add-key",[16,3644,3646],{"id":3645},"step-6-start-ssh-agent-and-verify-key","Step 6: Start SSH Agent And Verify Key",[261,3648,3649,3657],{"gap":263,"left-width":265,"right-width":483},[268,3650,3651,3653],{"v-slot:left":270},[108,3652,631],{},[540,3654],{"label":3655,"language":542,"src":3656},"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",[268,3658,3659,3661],{"v-slot:right":270},[108,3660,660],{},[540,3662],{"label":3409,"language":3026,"src":3663},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-08.txt",[20,3665,3666,3672,3693],{},[23,3667,3668,3671],{},[70,3669,3670],{},"eval \"$(ssh-agent -s)\""," starts the SSH helper GitHub docs usually show",[23,3673,3674,3675,3678,3679,3682],{},"If that fails, run ",[70,3676,3677],{},"exec ssh-agent bash",", then run ",[70,3680,3681],{},"ssh-add ~\u002F.ssh\u002Fgithub_key",[20,3683,3684],{},[23,3685,1960,3686,3689,3690,3692],{},[70,3687,3688],{},"~\u002F.ssh\u002Fgithub_key"," because ",[70,3691,1602],{}," avoids issues with spaces in home directory paths",[23,3694,3695],{},"Then verify the key is loaded",[261,3697,3698,3706],{"gap":263,"left-width":483,"right-width":483},[268,3699,3700,3702],{"v-slot:left":270},[108,3701,631],{},[540,3703],{"label":3704,"language":542,"src":3705},"verify-loaded-key.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fverify-loaded-key-09.sh",[268,3707,3708,3710,3713],{"v-slot:right":270},[108,3709,3023],{},[540,3711],{"label":3409,"language":3026,"src":3712},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-10.txt",[108,3714,3715],{},"One loaded key is enough for this lesson",[11,3717,3719,3723,3740],{"id":3718,"level":14},"step-6-copy-public-key",[16,3720,3722],{"id":3721},"step-7-copy-public-key","Step 7: Copy Public Key",[261,3724,3725,3733],{"gap":263,"left-width":483,"right-width":483},[268,3726,3727,3729],{"v-slot:left":270},[108,3728,631],{},[540,3730],{"label":3731,"language":542,"src":3732},"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",[268,3734,3735,3737],{"v-slot:right":270},[108,3736,660],{},[540,3738],{"label":3409,"language":3026,"src":3739},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-12.txt",[20,3741,3742,3752],{},[23,3743,3744,3745,3748,3749,3751],{},"Copy the full line starting with ",[70,3746,3747],{},"ssh-ed25519"," and ending with the value you set with ",[70,3750,3608],{}," earlier",[23,3753,3754,3755,3757],{},"Do not copy ",[70,3756,3555],{},", which is the private key (never share the private key)",[11,3759,3761,3765],{"id":3760,"level":14},"step-7-add-key-to-github",[16,3762,3764],{"id":3763},"step-8-add-key-to-github","Step 8: Add Key To GitHub",[20,3766,3767,3770,3775,3778,3781],{},[23,3768,3769],{},"In GitHub, open account settings",[23,3771,360,3772],{},[70,3773,3774],{},"SSH and GPG keys",[23,3776,3777],{},"Add a new authentication key",[23,3779,3780],{},"Paste the public key from the previous step",[23,3782,3783],{},"See the slides below for the GitHub screens",[11,3785,3787,3791],{"id":3786,"level":255},"step-8-open-github-settings",[179,3788,3790],{"id":3789},"open-github-settings","Open GitHub Settings",[261,3792,3793,3801],{"gap":263,"left-width":265,"right-width":264,"stack":2509},[268,3794,3795],{"v-slot:left":270},[108,3796,3797],{},[334,3798],{"alt":3799,"src":3800,"variant":338},"GitHub profile menu with Settings highlighted","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-01-gh-menu.png",[268,3802,3803],{"v-slot:right":270},[20,3804,3805,3808,3813],{},[23,3806,3807],{},"Click your GitHub profile photo",[23,3809,3474,3810],{},[70,3811,3812],{},"Settings",[23,3814,3815],{},"Use the account menu, not the repository settings",[11,3817,3819,3823],{"id":3818,"level":255},"step-8-open-ssh-keys-page",[179,3820,3822],{"id":3821},"open-ssh-and-gpg-keys","Open SSH And GPG Keys",[261,3824,3825,3833],{"gap":263,"left-width":265,"right-width":264,"stack":2509},[268,3826,3827],{"v-slot:left":270},[108,3828,3829],{},[334,3830],{"alt":3831,"src":3832,"variant":338},"GitHub settings sidebar with SSH and GPG keys selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fssh-key-02-gh-ssh-link.png",[268,3834,3835],{"v-slot:right":270},[20,3836,3837,3844,3849],{},[23,3838,3839,3840,3843],{},"Find the ",[70,3841,3842],{},"Access"," section",[23,3845,3846,3847],{},"Open ",[70,3848,3774],{},[23,3850,3474,3851],{},[70,3852,3853],{},"New SSH key",[11,3855,3857,3861],{"id":3856,"level":255},"step-8-add-new-ssh-key",[179,3858,3860],{"id":3859},"add-new-ssh-key","Add New SSH Key",[261,3862,3864,3872],{"gap":263,"left-width":3863,"right-width":3013,"stack":2509},"1.35fr",[268,3865,3866],{"v-slot:left":270},[108,3867,3868],{},[334,3869],{"alt":3870,"src":3871,"variant":338},"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",[268,3873,3874],{"v-slot:right":270},[20,3875,3876,3882,3888,3891,3896],{},[23,3877,3878,3879],{},"Title it clearly, such as ",[70,3880,3881],{},"\u003Ccourse> Laptop",[23,3883,3884,3885],{},"Keep key type as ",[70,3886,3887],{},"Authentication Key",[23,3889,3890],{},"Paste the full public key line",[23,3892,1004,3893],{},[70,3894,3895],{},"Add SSH key",[23,3897,3898],{},"Never paste the private key",[11,3900,3902,3906],{"id":3901,"level":14},"step-8-test-auth",[16,3903,3905],{"id":3904},"step-9-test-github-ssh-access","Step 9: Test GitHub SSH Access",[261,3907,3908,3923],{"gap":263,"left-width":483,"right-width":265},[268,3909,3910,3912,3916],{"v-slot:left":270},[108,3911,631],{},[540,3913],{"label":3914,"language":542,"src":3915},"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",[108,3917,3918,3919,3922],{},"If prompted the first time, type ",[70,3920,3921],{},"yes"," to trust GitHub's host key",[268,3924,3925,3927,3930],{"v-slot:right":270},[108,3926,3023],{},[540,3928],{"label":3409,"language":3026,"src":3929},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-14.txt",[108,3931,3932],{},"This confirms authentication, then GitHub closes the connection",[11,3934,3936,3940],{"id":3935,"level":14},"step-9-clone-repo",[16,3937,3939],{"id":3938},"step-10-clone-course-repository","Step 10: Clone Course Repository",[261,3941,3942,3983],{"gap":263,"left-width":264,"right-width":265},[268,3943,3944,3948,3977],{"v-slot:left":270},[179,3945,3947],{"id":3946},"get-the-ssh-clone-url","Get The SSH Clone URL",[20,3949,3950,3956,3963,3970],{},[23,3951,3952,3953],{},"In your GitHub repository, click ",[70,3954,3955],{},"Code",[23,3957,3958,3959,3962],{},"Choose the ",[70,3960,3961],{},"SSH"," tab",[23,3964,3965,3966,3969],{},"Copy the ",[70,3967,3968],{},"git@github.com:..."," link",[23,3971,3972,3973,3976],{},"Use that link in the ",[70,3974,3975],{},"git clone"," command",[108,3978,3979],{},[334,3980],{"alt":3981,"src":3982,"variant":338},"GitHub repository Code menu with SSH clone URL selected","\u002Fimages\u002Finternet-applications\u002Fgithub-ssh\u002Fgithub-clone-url.png",[268,3984,3985,3988,3992],{"v-slot:right":270},[108,3986,3987],{},"Run from the folder that should contain your course repo:",[540,3989],{"label":3990,"language":542,"src":3991},"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",[2725,3993,3995],{"type":3994},"tip",[108,3996,3997,3998,4001],{},"Before cloning, run ",[70,3999,4000],{},"git rev-parse --show-toplevel",". If it prints a path, move somewhere else first. Clone this repo only once.",[108,4003,660],{},[540,4005],{"label":3409,"language":3026,"src":4006},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-16.txt",[108,4008,4009,4010,4013,4014,4017],{},"If you see an empty repository warning, you probably forgot to add ",[70,4011,4012],{},"README.md"," when creating the repo. Create it with ",[70,4015,4016],{},"touch README.md",", then use the add\u002Fcommit\u002Fpush commands from the next lesson\n::\n::",[11,4019,4021,4025,4044,4063,4083],{"id":4020,"level":14},"step-10-set-repo-identity",[16,4022,4024],{"id":4023},"step-11-set-repo-git-identity","Step 11: Set Repo Git Identity",[261,4026,4027,4036],{"gap":263,"left-width":483,"right-width":483},[268,4028,4029,4032],{"v-slot:left":270},[108,4030,4031],{},"Run inside the cloned repository:",[540,4033],{"label":4034,"language":542,"src":4035},"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",[268,4037,4038,4040],{"v-slot:right":270},[108,4039,3023],{},[540,4041],{"label":4042,"language":3026,"src":4043},"config-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-19.txt",[261,4045,4046,4055],{"gap":263,"left-width":483,"right-width":483},[268,4047,4048,4051],{"v-slot:left":270},[108,4049,4050],{},"Then verify:",[540,4052],{"label":4053,"language":542,"src":4054},"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",[268,4056,4057,4059],{"v-slot:right":270},[108,4058,3023],{},[540,4060],{"label":4061,"language":3026,"src":4062},"identity-output.txt","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh\u002Fexample-output-20.txt",[20,4064,4065,4071,4077],{},[23,4066,4067,4070],{},[70,4068,4069],{},"user.name"," can be your real or display name, though commonly it's your GitHub username",[23,4072,4073,4076],{},[70,4074,4075],{},"user.email"," should match a GitHub email or GitHub no-reply address for commit linking to work (this is important)",[23,4078,4079,4082],{},[70,4080,4081],{},"core.sshCommand"," tells this repository to use your course GitHub key",[108,4084,4085,4086,4089],{},"These commands set identity for this repository. The ",[70,4087,4088],{},"--global"," flag is an option only if you intentionally want the same identity for all repositories",[11,4091,4093,4097,4100,4116],{"id":4092,"level":14},"step-11-invite-collaborators",[16,4094,4096],{"id":4095},"step-12-invite-course-collaborators","Step 12: Invite Course Collaborators",[108,4098,4099],{},"In GitHub, open your course repository:",[20,4101,4102,4105,4110,4113],{},[23,4103,4104],{},"Settings -> Collaborators and teams",[23,4106,4107,4108],{},"Invite ",[70,4109,1211],{},[23,4111,4112],{},"Invite your TA if your section has one",[23,4114,4115],{},"Wait until the invitation shows as sent or accepted",[108,4117,4118],{},"This is so it can be accessed for grading and assistance",[11,4120,4122,4125],{"id":4121,"level":14},"troubleshooting-auth",[16,4123,4124],{"id":4121},"Troubleshooting Auth",[20,4126,4127,4133,4140,4147,4150],{},[23,4128,4129,4132],{},[70,4130,4131],{},"Permission denied (publickey)",": GitHub did not accept a loaded key",[23,4134,4135,4136,4139],{},"No loaded key in ",[70,4137,4138],{},"ssh-add -l",": start the agent and add the key again",[23,4141,4142,4143,4146],{},"Wrong key in GitHub: delete it and paste the ",[70,4144,4145],{},".pub"," key again",[23,4148,4149],{},"Wrong account: make sure the success message names your GitHub account",[23,4151,4152],{},"See the slide below for a quick reset sequence",[11,4154,4156,4160,4162,4189],{"id":4155,"level":255},"troubleshooting-auth-recovery",[179,4157,4159],{"id":4158},"quick-reset-sequence","Quick Reset Sequence",[108,4161,631],{},[410,4163,4164,4168,4172,4176,4181,4184],{},[23,4165,4166],{},[70,4167,3670],{},[23,4169,4170],{},[70,4171,3681],{},[23,4173,4174],{},[70,4175,4138],{},[23,4177,4178],{},[70,4179,4180],{},"cat ~\u002F.ssh\u002Fgithub_key.pub",[23,4182,4183],{},"Re-paste the public key in GitHub if needed",[23,4185,4186],{},[70,4187,4188],{},"ssh -T git@github.com",[108,4190,2970,4191,4193,4194,4196,4197,4200],{},[70,4192,3670],{}," fails in Git Bash, use ",[70,4195,3677],{},", then repeat the ",[70,4198,4199],{},"ssh-add"," steps",[11,4202,4203,4205,4208],{"id":698,"level":14},[16,4204,701],{"id":698},[108,4206,4207],{},"You are done when all are true:",[20,4209,4210,4215,4222,4227,4230,4235,4238],{},[23,4211,4212,4214],{},[70,4213,2438],{}," works",[23,4216,4217,4219,4220],{},[70,4218,4138],{}," shows ",[70,4221,3555],{},[23,4223,4224,4226],{},[70,4225,4188],{}," names your GitHub account",[23,4228,4229],{},"Your private course repository exists on GitHub",[23,4231,4232,4234],{},[70,4233,1211],{}," and your TA, if applicable, are invited as collaborators",[23,4236,4237],{},"Your local terminal is open to the cloned repository",[23,4239,4240,322,4243,4246],{},[70,4241,4242],{},"git config user.name",[70,4244,4245],{},"git config user.email"," return your repo identity",[11,4248,4249,4251],{"id":754,"level":14},[16,4250,727],{"id":724},[261,4252,4253,4281],{"gap":263,"left-width":483,"right-width":483},[268,4254,4255,4257,4263,4269,4275],{"v-slot:left":270},[179,4256,735],{"id":734},[108,4258,4259,4262],{},[963,4260,4261],{},"Git identity"," - commit name and email saved in repo config",[108,4264,4265,4268],{},[963,4266,4267],{},"SSH key pair"," - private key on your computer, public key in GitHub",[108,4270,4271,4274],{},[963,4272,4273],{},"SSH agent"," - background helper that makes your private key available",[108,4276,4277,4280],{},[963,4278,4279],{},"Clone"," - local copy of a GitHub repository",[268,4282,4283,4285],{"v-slot:right":270},[179,4284,755],{"id":754},[20,4286,4287,4294,4301,4308],{},[23,4288,4289],{},[86,4290,4293],{"href":4291,"rel":4292},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Fgenerating-a-new-ssh-key-and-adding-it-to-the-ssh-agent",[90],"GitHub Docs: Generate a new SSH key and add it to the ssh-agent",[23,4295,4296],{},[86,4297,4300],{"href":4298,"rel":4299},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fauthentication\u002Fconnecting-to-github-with-ssh\u002Ftesting-your-ssh-connection",[90],"GitHub Docs: Testing your SSH connection",[23,4302,4303],{},[86,4304,4307],{"href":4305,"rel":4306},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcreating-a-new-repository",[90],"GitHub Docs: Create a repository",[23,4309,4310],{},[86,4311,4314],{"href":4312,"rel":4313},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fcreating-and-managing-repositories\u002Fcloning-a-repository",[90],"GitHub Docs: Cloning a repository",[11,4316,4317,4319,4321],{"id":781,"level":14},[16,4318,784],{"id":781},[108,4320,2325],{},[20,4322,4323,4326,4329,4332,4335,4338,4344],{},[23,4324,4325],{},"Use the correct terminal for your operating system",[23,4327,4328],{},"Authenticate to GitHub with SSH",[23,4330,4331],{},"Find your private course repository on GitHub",[23,4333,4334],{},"Invite course collaborators",[23,4336,4337],{},"Open the local clone in the terminal",[23,4339,4340,4341],{},"Show repo-local Git identity with ",[70,4342,4343],{},"git config",[23,4345,4346],{},"Next: practice the Git commands used for course work",{"title":270,"searchDepth":424,"depth":424,"links":4348},[4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4365,4366,4367,4368,4369,4372,4373,4374],{"id":3307,"depth":424,"text":3310},{"id":3333,"depth":424,"text":3336},{"id":3351,"depth":424,"text":3354},{"id":3376,"depth":424,"text":3379},{"id":3389,"depth":424,"text":3392},{"id":3419,"depth":424,"text":3420},{"id":3456,"depth":424,"text":3457},{"id":3531,"depth":424,"text":3532},{"id":3578,"depth":424,"text":3579},{"id":3645,"depth":424,"text":3646},{"id":3721,"depth":424,"text":3722},{"id":3763,"depth":424,"text":3764,"children":4361},[4362,4363,4364],{"id":3789,"depth":437,"text":3790},{"id":3821,"depth":437,"text":3822},{"id":3859,"depth":437,"text":3860},{"id":3904,"depth":424,"text":3905},{"id":3938,"depth":424,"text":3939},{"id":4023,"depth":424,"text":4024},{"id":4095,"depth":424,"text":4096},{"id":4121,"depth":424,"text":4124,"children":4370},[4371],{"id":4158,"depth":437,"text":4159},{"id":698,"depth":424,"text":701},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"Connect your computer to GitHub with SSH, create the course repository, clone it, and set repo-local Git identity.","Face-to-face class of about 40 students; includes GitHub account check, SSH key generation, GitHub UI steps, repo creation, clone troubleshooting, repo-local Git identity, and authentication checks.","15","70","85",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",{"title":3302,"description":4375},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F03-setup-github-ssh",[2628,4385,4386,4387],"github","ssh","repository","48:26","HZG3_HfczOk","https:\u002F\u002Fyoutu.be\u002FHZG3_HfczOk","Setup Git SSH and GitHub","rJ2RP6nrPEoOj98kzeevFpO0YOXaJl-M5ajP_tsjwvA",{"id":4394,"title":4395,"audience":6,"body":4396,"contentType":832,"course":158,"description":5315,"estimateBasis":5316,"estimatedDiscussionMinutes":1337,"estimatedLiveMinutes":4378,"estimatedTotalMinutes":5317,"extension":838,"meta":5318,"module":840,"navigation":841,"order":837,"path":5319,"promptAssist":844,"seo":5320,"status":846,"stem":5321,"tags":5322,"videoDuration":5325,"videoId":5326,"videoLink":5327,"videoTitle":5328,"week":840,"__hash__":5329},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs.md","Git Commands And Pull Requests",{"type":8,"value":4397,"toc":5280},[4398,4427,4448,4464,4496,4530,4581,4597,4618,4649,4681,4723,4754,4789,4813,4858,4885,4915,4933,4945,4981,5014,5050,5084,5110,5138,5168,5235,5277],[11,4399,4401,4404,4407],{"id":4400,"level":14},"objectives",[16,4402,4403],{"id":4400},"Objectives",[108,4405,4406],{},"By the end, you should be able to:",[20,4408,4409,4412,4415,4418,4421,4424],{},[23,4410,4411],{},"Explain what the common Git commands do",[23,4413,4414],{},"Connect commands to the working folder, staging area, local commits, and GitHub remote",[23,4416,4417],{},"Create a branch for practice work",[23,4419,4420],{},"Stage, commit, and push a small change",[23,4422,4423],{},"Open a pull request on GitHub",[23,4425,4426],{},"Investigate a failed push and a merge conflict",[11,4428,4430,4434,4437,4440],{"id":4429,"level":14},"git-vs-github",[16,4431,4433],{"id":4432},"git-versus-github","Git Versus GitHub",[108,4435,4436],{},"Git is the tool that tracks file history",[108,4438,4439],{},"GitHub is a website that hosts a remote copy of a Git repository",[20,4441,4442,4445],{},[23,4443,4444],{},"Git: local terminal workflow",[23,4446,4447],{},"GitHub: remote branches, pull requests, issues, and project evidence",[11,4449,4451,4455,4458,4461],{"id":4450,"level":14},"git-stages",[16,4452,4454],{"id":4453},"the-git-stages","The Git Stages",[540,4456],{"language":663,"src":4457},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-01.txt",[108,4459,4460],{},"Common commands:",[540,4462],{"language":663,"src":4463},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fthe-git-stages-02.txt",[11,4465,4467,4471,4473,4476,4479,4482],{"id":4466,"level":14},"status-first",[16,4468,4470],{"id":4469},"command-1-git-status","Command 1: git status",[108,4472,631],{},[540,4474],{"language":542,"src":4475},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-1-git-status-03.sh",[108,4477,4478],{},"Use this before and after every important Git action",[108,4480,4481],{},"It tells you:",[20,4483,4484,4487,4490,4493],{},[23,4485,4486],{},"Current branch",[23,4488,4489],{},"Changed files",[23,4491,4492],{},"Staged files",[23,4494,4495],{},"Whether your working tree is clean",[11,4497,4499,4503,4505,4508],{"id":4498,"level":14},"branch-command",[16,4500,4502],{"id":4501},"command-2-git-branch","Command 2: git branch",[108,4504,631],{},[540,4506],{"language":542,"src":4507},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-2-git-branch-04.sh",[20,4509,4510,4513,4516],{},[23,4511,4512],{},"Active branch has an asterisk",[23,4514,4515],{},"Branches are separate timelines for work",[23,4517,4518,4519],{},"Branch names are case-sensitive\n",[20,4520,4521],{},[23,4522,4523,322,4526,4529],{},[70,4524,4525],{},"Practice",[70,4527,4528],{},"practice"," are different names",[11,4531,4533,4537,4542,4545],{"id":4532,"level":14},"create-branch",[16,4534,4536],{"id":4535},"practice-step-1-create-a-branch","Practice Step 1: Create A Branch",[108,4538,4539,4540,2067],{},"Start from ",[70,4541,2593],{},[540,4543],{"language":542,"src":4544},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-1-create-a-05.sh",[20,4546,4547,4558],{},[23,4548,4549,4550,4552,4553],{},"First two commands: make sure ",[70,4551,2593],{}," is current\n",[20,4554,4555],{},[23,4556,4557],{},"Explained more later",[23,4559,4560,4561],{},"Branch control commands\n",[20,4562,4563,4569,4575],{},[23,4564,4565,4568],{},[70,4566,4567],{},"git checkout -b practice",": create and switch",[23,4570,4571,4574],{},[70,4572,4573],{},"git branch practice",": create only",[23,4576,4577,4580],{},[70,4578,4579],{},"git checkout practice",": switch to existing",[11,4582,4584,4588,4591,4594],{"id":4583,"level":14},"make-file",[16,4585,4587],{"id":4586},"practice-step-2-make-a-small-file","Practice Step 2: Make A Small File",[108,4589,4590],{},"Create a small practice file:",[540,4592],{"language":542,"src":4593},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpractice-step-2-make-a-s-06.sh",[108,4595,4596],{},"Expected result: Git shows the new file as untracked",[11,4598,4600,4604,4607,4610,4613],{"id":4599,"level":14},"add-command",[16,4601,4603],{"id":4602},"command-3-git-add","Command 3: git add",[108,4605,4606],{},"Stage the new file:",[540,4608],{"language":542,"src":4609},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-3-git-add-07.sh",[108,4611,4612],{},"Staging means: include this change in the next commit",[20,4614,4615],{},[23,4616,4617],{},"See below for add patterns and verification checks",[11,4619,4621,4625,4628,4631],{"id":4620,"level":255},"add-variants",[179,4622,4624],{"id":4623},"common-git-add-patterns","Common git add Patterns",[108,4626,4627],{},"Use the smallest clear target when possible",[540,4629],{"language":542,"src":4630},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommon-git-add-patterns-08.sh",[20,4632,4633,4636,4639],{},[23,4634,4635],{},"Single file: safest when you changed one file",[23,4637,4638],{},"Folder: useful when one feature is grouped in one folder",[23,4640,4641,4644,4645,4648],{},[70,4642,4643],{},"git add .",": convenient, but review ",[70,4646,4647],{},"git status"," first",[11,4650,4652,4656,4659,4662],{"id":4651,"level":14},"diff-command",[16,4653,4655],{"id":4654},"command-4-git-diff","Command 4: git diff",[108,4657,4658],{},"Before committing, inspect what changed:",[540,4660],{"language":542,"src":4661},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-4-git-diff-09.sh",[20,4663,4664,4671,4674,4679],{},[23,4665,4666,4667,4670],{},"New untracked file: ",[70,4668,4669],{},"git diff"," may show nothing",[23,4672,4673],{},"That does not mean the file is missing",[23,4675,1960,4676,4678],{},[70,4677,4647],{}," to confirm untracked files",[23,4680,2129],{},[11,4682,4684,4688,4691,4694,4697,4700],{"id":4683,"level":255},"cached-rm",[179,4685,4687],{"id":4686},"if-you-staged-the-wrong-file","If You Staged The Wrong File",[108,4689,4690],{},"If a file was staged by mistake, remove it from staging:",[540,4692],{"language":542,"src":4693},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--10.sh",[108,4695,4696],{},"For a folder:",[540,4698],{"language":542,"src":4699},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fif-you-staged-the-wrong--11.sh",[20,4701,4702,4713],{},[23,4703,4704,4707,4708],{},[70,4705,4706],{},"--cached",": remove from staging only\n",[20,4709,4710],{},[23,4711,4712],{},"Keeps the file in your working folder",[23,4714,4715,4717,4718],{},[70,4716,1439],{},": folder mode\n",[20,4719,4720],{},[23,4721,4722],{},"Recursive: include files inside the folder",[11,4724,4726,4730,4733,4736,4739],{"id":4725,"level":14},"commit-command",[16,4727,4729],{"id":4728},"command-5-git-commit","Command 5: git commit",[108,4731,4732],{},"Commit the staged file:",[540,4734],{"language":542,"src":4735},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-5-git-commit-12.sh",[108,4737,4738],{},"A commit is a saved checkpoint in your local repository",[20,4740,4741,4752],{},[23,4742,4743,4746,4747],{},[70,4744,4745],{},"-m",": commit message",[20,4748,4749],{},[23,4750,4751],{},"Required, even if the message is an empty string",[23,4753,2129],{},[11,4755,4757,4761,4763,4766,4786],{"id":4756,"level":255},"log-command",[179,4758,4760],{"id":4759},"check-the-local-history","Check The Local History",[108,4762,631],{},[540,4764],{"language":542,"src":4765},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcheck-the-local-history-13.sh",[20,4767,4768,4774,4780],{},[23,4769,4770,4773],{},[70,4771,4772],{},"log",": show commit history",[23,4775,4776,4779],{},[70,4777,4778],{},"--oneline",": one commit per line",[23,4781,4782,4785],{},[70,4783,4784],{},"-5",": show the latest five commits",[108,4787,4788],{},"You should see your latest commit near the top",[11,4790,4792,4796,4799,4802],{"id":4791,"level":14},"push-command",[16,4793,4795],{"id":4794},"command-6-git-push","Command 6: git push",[108,4797,4798],{},"Send the branch to GitHub:",[540,4800],{"language":542,"src":4801},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fcommand-6-git-push-14.sh",[20,4803,4804,4810],{},[23,4805,4806,4809],{},[70,4807,4808],{},"origin",": common remote name for GitHub",[23,4811,4812],{},"Final part: branch you are pushing",[11,4814,4816,4820],{"id":4815,"level":14},"open-pr",[16,4817,4819],{"id":4818},"pull-request","Pull Request",[261,4821,4822,4850],{"gap":263,"left-width":483,"right-width":483},[268,4823,4824,4827,4830,4833,4836,4839],{"v-slot:left":270},[108,4825,4826],{},"On GitHub, open a pull request",[108,4828,4829],{},"Use this direction:",[540,4831],{"language":663,"src":4832},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-15.txt",[108,4834,4835],{},"Use a clear description:",[540,4837],{"language":663,"src":4838},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-request-description-16.txt",[20,4840,4841,4844,4847],{},[23,4842,4843],{},"Review page before merge",[23,4845,4846],{},"Shows what will change",[23,4848,4849],{},"Captures branch evidence",[268,4851,4852],{"v-slot:right":270},[108,4853,4854],{},[334,4855],{"alt":4856,"src":4857,"variant":338},"GitHub pull request creation page showing base main and compare practice","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgithub-create-pull-request.png",[11,4859,4861,4865,4868,4876,4879,4882],{"id":4860,"level":14},"merge-pr",[16,4862,4864],{"id":4863},"merge-and-sync","Merge And Sync",[108,4866,4867],{},"After GitHub merge:",[20,4869,4870],{},[23,4871,4872,4873,4875],{},"Local ",[70,4874,2593],{}," is not updated automatically",[108,4877,4878],{},"Sync it:",[540,4880],{"language":542,"src":4881},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fmerge-and-sync-15.sh",[108,4883,4884],{},"Remote changes must be pulled down intentionally",[11,4886,4888,4892,4895,4912],{"id":4887,"level":14},"why-prs",[16,4889,4891],{"id":4890},"why-pull-requests-matter","Why Pull Requests Matter",[108,4893,4894],{},"Pull requests create evidence:",[20,4896,4897,4900,4903,4906,4909],{},[23,4898,4899],{},"Which branch changed",[23,4901,4902],{},"Which files changed",[23,4904,4905],{},"What discussion or explanation was provided",[23,4907,4908],{},"Chance to review risky changes before merging",[23,4910,4911],{},"When the change was merged",[108,4913,4914],{},"For this course, pull requests are part of the workflow evidence, not just a GitHub feature",[11,4916,4918,4922,4925],{"id":4917,"level":14},"exploration-intro",[16,4919,4921],{"id":4920},"troubleshooting-explorations","Troubleshooting Explorations",[108,4923,4924],{},"The next slides use controlled problems to practice recovery",[20,4926,4927,4930],{},[23,4928,4929],{},"The goal is not avoiding every error",[23,4931,4932],{},"The goal is reading output, identifying state, and recovering without guessing",[11,4934,4936,4939,4942],{"id":4935,"level":14},"exploration-setup",[16,4937,4938],{"id":4935},"Exploration Setup",[108,4940,4941],{},"Create a conflict practice branch:",[540,4943],{"language":542,"src":4944},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-setup-16.sh",[11,4946,4948,4952,4958,4965,4970,4973,4976],{"id":4947,"level":14},"exploration-issue-1",[16,4949,4951],{"id":4950},"exploration-issue-1-push-rejected","Exploration Issue 1: Push Rejected",[108,4953,4954,4955],{},"On GitHub, switch to ",[70,4956,4957],{},"practice-conflict",[108,4959,4960,4961,4964],{},"Edit one line in ",[70,4962,4963],{},"myFile.txt"," directly on GitHub and commit the change",[20,4966,4967],{},[23,4968,4969],{},"Use the same line you will change locally",[108,4971,4972],{},"Back locally, edit that same line and commit:",[540,4974],{"language":542,"src":4975},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-1-push-17.sh",[20,4977,4978],{},[23,4979,4980],{},"See the slides below for the rejected push and the pull that creates the conflict",[11,4982,4984,4988,4991],{"id":4983,"level":255},"issue-1-push-without-pulling",[179,4985,4987],{"id":4986},"try-push-without-pulling","Try Push Without Pulling",[108,4989,4990],{},"Push the local commit before pulling the GitHub commit:",[261,4992,4993,5006],{"gap":263,"left-width":483,"right-width":483},[268,4994,4995,4998],{"v-slot:left":270},[540,4996],{"language":542,"src":4997},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Ftry-push-without-pulling-20.sh",[20,4999,5000,5003],{},[23,5001,5002],{},"Expected result: push rejected",[23,5004,5005],{},"Reason: GitHub has a commit your local branch does not have",[268,5007,5008],{"v-slot:right":270},[108,5009,5010],{},[334,5011],{"alt":5012,"src":5013,"variant":338},"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,5015,5017,5021],{"id":5016,"level":255},"issue-1-read-output",[179,5018,5020],{"id":5019},"pull-the-remote-change","Pull The Remote Change",[261,5022,5023,5042],{"gap":263,"left-width":483,"right-width":483},[268,5024,5025,5028,5031,5034,5039],{"v-slot:left":270},[108,5026,5027],{},"The usual next command is:",[540,5029],{"language":542,"src":5030},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-20.sh",[108,5032,5033],{},"If Git asks how to reconcile divergent branches:",[20,5035,5036],{},[23,5037,5038],{},"Use merge behavior for this course practice",[540,5040],{"language":542,"src":5041},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fpull-the-remote-change-21.sh",[268,5043,5044],{"v-slot:right":270},[108,5045,5046],{},[334,5047],{"alt":5048,"src":5049,"variant":338},"Git pull output asking how to reconcile divergent branches","\u002Fimages\u002Fshared\u002Fgit-workflow\u002Fgit-pull-divergent-branches.png",[11,5051,5053,5057,5060,5064,5067,5070,5073],{"id":5052,"level":14},"exploration-issue-2",[16,5054,5056],{"id":5055},"exploration-issue-2-merge-conflict","Exploration Issue 2: Merge Conflict",[108,5058,5059],{},"After pulling, Git should report a conflict",[108,5061,3846,5062],{},[70,5063,4963],{},[108,5065,5066],{},"You may see markers like:",[540,5068],{"language":663,"src":5069},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fexploration-issue-2-merg-18.txt",[108,5071,5072],{},"Conflict markers show:",[20,5074,5075,5078,5081],{},[23,5076,5077],{},"Your local version",[23,5079,5080],{},"The GitHub version",[23,5082,5083],{},"The part Git could not combine automatically",[11,5085,5087,5091,5097,5100,5103,5106],{"id":5086,"level":255},"resolve-conflict",[179,5088,5090],{"id":5089},"resolve-the-conflict","Resolve The Conflict",[108,5092,5093,5094,5096],{},"Edit ",[70,5095,4963],{}," so it contains the final text you want",[108,5098,5099],{},"Remove all conflict markers",[108,5101,5102],{},"Then run:",[540,5104],{"language":542,"src":5105},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs\u002Fresolve-the-conflict-19.sh",[20,5107,5108],{},[23,5109,2129],{},[11,5111,5113,5117,5120],{"id":5112,"level":255},"verify-conflict-resolution",[179,5114,5116],{"id":5115},"verify-the-recovery","Verify The Recovery",[108,5118,5119],{},"Check:",[20,5121,5122,5127,5130,5135],{},[23,5123,5124,5126],{},[70,5125,4647],{}," is clean",[23,5128,5129],{},"GitHub shows the updated branch",[23,5131,5132,5134],{},[70,5133,4963],{}," contains the final text",[23,5136,5137],{},"No conflict markers remain",[11,5139,5140,5142],{"id":678,"level":14},[16,5141,681],{"id":678},[20,5143,5144,5147,5150,5153,5156,5165],{},[23,5145,5146],{},"Committing on the wrong branch",[23,5148,5149],{},"Forgetting to push after committing",[23,5151,5152],{},"Forgetting to pull after merging on GitHub",[23,5154,5155],{},"Leaving conflict markers in a file",[23,5157,5158,5159,159,5162],{},"Using vague branch names like ",[70,5160,5161],{},"stuff",[70,5163,5164],{},"final",[23,5166,5167],{},"Making several unrelated changes in one commit",[11,5169,5170,5172],{"id":754,"level":14},[16,5171,727],{"id":724},[261,5173,5174,5198],{"gap":263,"left-width":483,"right-width":483},[268,5175,5176,5178],{"v-slot:left":270},[179,5177,735],{"id":734},[20,5179,5180,5183,5186,5189,5192,5195],{},[23,5181,5182],{},"Working folder: files you can edit",[23,5184,5185],{},"Staging area: changes selected for the next commit",[23,5187,5188],{},"Commit: local saved checkpoint",[23,5190,5191],{},"Remote: GitHub copy of the repository",[23,5193,5194],{},"Pull request: GitHub page for reviewing and merging branch work",[23,5196,5197],{},"Conflict: a change Git cannot merge automatically",[268,5199,5200,5202],{"v-slot:right":270},[179,5201,755],{"id":754},[20,5203,5204,5212,5219,5227],{},[23,5205,5206,5207],{},"Pro Git Book: ",[86,5208,5211],{"href":5209,"rel":5210},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Basics-Getting-a-Git-Repository",[90],"Git Basics",[23,5213,5206,5214],{},[86,5215,5218],{"href":5216,"rel":5217},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Basic-Branching-and-Merging",[90],"Basic Branching and Merging",[23,5220,5221,5222],{},"GitHub Docs: ",[86,5223,5226],{"href":5224,"rel":5225},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fcreating-a-pull-request",[90],"Creating a pull request",[23,5228,5229,5230],{},"Oh Shit, Git!?!: ",[86,5231,5234],{"href":5232,"rel":5233},"https:\u002F\u002Fohshitgit.com\u002F",[90],"Common Git recovery situations",[11,5236,5237,5239],{"id":781,"level":14},[16,5238,784],{"id":781},[261,5240,5243,5267],{"gap":838,"left-width":5241,"right-width":5242},"0.72fr","1.38fr",[268,5244,5245,5247],{"v-slot:left":270},[108,5246,2325],{},[20,5248,5249,5255,5258,5261,5264],{},[23,5250,5251,5252,5254],{},"Read ",[70,5253,4647],{}," before choosing the next command",[23,5256,5257],{},"Move a change from working folder to staging area to commit",[23,5259,5260],{},"Push a branch to GitHub and open a pull request",[23,5262,5263],{},"Recognize when a failed push or conflict needs recovery",[23,5265,5266],{},"Next: open the cloned repository in VS Code",[268,5268,5269,5272],{"v-slot:right":270},[108,5270,5271],{},"Git\u002FGitHub flow:",[5273,5274],"figure-image",{"alt":5275,"src":5276},"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",[108,5278,5279],{},"::",{"title":270,"searchDepth":424,"depth":424,"links":5281},[5282,5283,5284,5285,5286,5287,5288,5289,5292,5295,5298,5299,5300,5301,5302,5303,5304,5308,5312,5313,5314],{"id":4400,"depth":424,"text":4403},{"id":4432,"depth":424,"text":4433},{"id":4453,"depth":424,"text":4454},{"id":4469,"depth":424,"text":4470},{"id":4501,"depth":424,"text":4502},{"id":4535,"depth":424,"text":4536},{"id":4586,"depth":424,"text":4587},{"id":4602,"depth":424,"text":4603,"children":5290},[5291],{"id":4623,"depth":437,"text":4624},{"id":4654,"depth":424,"text":4655,"children":5293},[5294],{"id":4686,"depth":437,"text":4687},{"id":4728,"depth":424,"text":4729,"children":5296},[5297],{"id":4759,"depth":437,"text":4760},{"id":4794,"depth":424,"text":4795},{"id":4818,"depth":424,"text":4819},{"id":4863,"depth":424,"text":4864},{"id":4890,"depth":424,"text":4891},{"id":4920,"depth":424,"text":4921},{"id":4935,"depth":424,"text":4938},{"id":4950,"depth":424,"text":4951,"children":5305},[5306,5307],{"id":4986,"depth":437,"text":4987},{"id":5019,"depth":437,"text":5020},{"id":5055,"depth":424,"text":5056,"children":5309},[5310,5311],{"id":5089,"depth":437,"text":5090},{"id":5115,"depth":437,"text":5116},{"id":678,"depth":424,"text":681},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"Practice the core Git workflow with small changes, branches, pull requests, and two guided troubleshooting scenarios.","Face-to-face class of about 40 students; includes command explanation, branch practice, pull request walkthrough, conflict exploration, and recovery discussion.","90",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",{"title":4395,"description":5315},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F04-git-commands-prs",[2628,5323,5324],"branches","pull-requests","48:54","MOa9zIUOqaI","https:\u002F\u002Fyoutu.be\u002FMOa9zIUOqaI","Git Commands and PRs","GTIGHU5IyAE7RcRy68evvCM5YPZVDAWUbiTdBfC9nCI",{"id":4,"title":5,"audience":6,"body":5331,"contentType":832,"course":158,"description":833,"estimateBasis":834,"estimatedDiscussionMinutes":835,"estimatedLiveMinutes":836,"estimatedTotalMinutes":837,"extension":838,"meta":5890,"module":840,"navigation":841,"order":842,"path":843,"promptAssist":844,"seo":5891,"status":846,"stem":847,"tags":5892,"videoDuration":852,"videoId":853,"videoLink":854,"videoTitle":855,"week":840,"__hash__":856},{"type":8,"value":5332,"toc":5868},[5333,5345,5359,5373,5390,5414,5436,5492,5545,5616,5636,5684,5737,5753,5773,5787,5805,5846],[11,5334,5335,5337],{"id":13,"level":14},[16,5336,5],{"id":18},[20,5338,5339,5341,5343],{},[23,5340,25],{},[23,5342,28],{},[23,5344,31],{},[11,5346,5347,5349],{"id":34,"level":14},[16,5348,37],{"id":34},[20,5350,5351,5353,5355,5357],{},[23,5352,42],{},[23,5354,45],{},[23,5356,48],{},[23,5358,51],{},[11,5360,5361,5363],{"id":54,"level":14},[16,5362,57],{"id":54},[20,5364,5365,5367,5369],{},[23,5366,62],{},[23,5368,65],{},[23,5370,68,5371,73],{},[70,5372,72],{},[11,5374,5375,5377],{"id":76,"level":14},[16,5376,79],{"id":76},[20,5378,5379,5384,5386,5388],{},[23,5380,84,5381],{},[86,5382,91],{"href":88,"rel":5383},[90],[23,5385,94],{},[23,5387,97],{},[23,5389,100],{},[11,5391,5392,5394,5396,5412],{"id":103,"level":14},[16,5393,106],{"id":103},[108,5395,110],{},[20,5397,5398,5404,5406,5410],{},[23,5399,115,5400,119,5402],{},[70,5401,118],{},[70,5403,122],{},[23,5405,125],{},[23,5407,128,5408],{},[70,5409,131],{},[23,5411,134],{},[108,5413,137],{},[11,5415,5416,5418,5434],{"id":140,"level":14},[16,5417,144],{"id":143},[20,5419,5420,5424,5430,5432],{},[23,5421,149,5422],{},[70,5423,152],{},[23,5425,155,5426,159,5428],{},[70,5427,158],{},[70,5429,162],{},[23,5431,165],{},[23,5433,168],{},[108,5435,171],{},[11,5437,5438,5440,5442],{"id":174,"level":14},[16,5439,177],{"id":174},[179,5441,182],{"id":181},[20,5443,5444,5450,5456,5462,5468,5474,5484,5490],{},[23,5445,187,5446],{},[20,5447,5448],{},[23,5449,192],{},[23,5451,195,5452],{},[20,5453,5454],{},[23,5455,200],{},[23,5457,203,5458],{},[20,5459,5460],{},[23,5461,208],{},[23,5463,211,5464],{},[20,5465,5466],{},[23,5467,216],{},[23,5469,219,5470],{},[20,5471,5472],{},[23,5473,224],{},[23,5475,227,5476],{},[20,5477,5478],{},[23,5479,232,5480,236,5482,240],{},[70,5481,235],{},[70,5483,239],{},[23,5485,243,5486],{},[20,5487,5488],{},[23,5489,248],{},[23,5491,251],{},[11,5493,5494,5496],{"id":254,"level":255},[16,5495,259],{"id":258},[261,5497,5498,5539],{"gap":263,"left-width":264,"right-width":265,"align":266},[268,5499,5500,5502],{"v-slot:left":270},[179,5501,274],{"id":273},[20,5503,5504,5506,5537],{},[23,5505,279],{},[23,5507,282,5508],{},[20,5509,5510,5514,5518,5520,5522],{},[23,5511,287,5512],{},[70,5513,290],{},[23,5515,293,5516],{},[70,5517,296],{},[23,5519,299],{},[23,5521,302],{},[23,5523,305,5524],{},[20,5525,5526,5531],{},[23,5527,310,5528],{},[86,5529,315],{"href":313,"rel":5530},[90],[23,5532,318,5533,322,5535],{},[70,5534,321],{},[70,5536,325],{},[23,5538,328],{},[268,5540,5541],{"v-slot:right":270},[108,5542,5543],{},[334,5544],{"alt":336,"src":337,"variant":338},[11,5546,5547,5549],{"id":341,"level":255},[16,5548,345],{"id":344},[261,5550,5551,5590],{"gap":263,"left-width":348,"right-width":349,"align":266},[268,5552,5553,5555],{"v-slot:left":270},[179,5554,355],{"id":354},[20,5556,5557,5562,5564,5566,5568,5570,5582,5586,5588],{},[23,5558,360,5559],{},[86,5560,365],{"href":363,"rel":5561},[90],[23,5563,368],{},[23,5565,371],{},[23,5567,374],{},[23,5569,377],{},[23,5571,380,5572],{},[20,5573,5574,5578],{},[23,5575,385,5576],{},[70,5577,388],{},[23,5579,391,5580],{},[70,5581,394],{},[23,5583,397,5584],{},[70,5585,400],{},[23,5587,403],{},[23,5589,406],{},[268,5591,5592,5596,5600,5604,5608,5612],{"v-slot:right":270},[410,5593,5594],{},[23,5595,414],{},[108,5597,5598],{},[334,5599],{"alt":419,"src":420,"variant":338,"max-height":421},[410,5601,5602],{"start":424},[23,5603,427],{},[108,5605,5606],{},[334,5607],{"alt":432,"src":433,"variant":338,"max-height":434},[410,5609,5610],{"start":437},[23,5611,440],{},[108,5613,5614],{},[334,5615],{"alt":445,"src":446,"variant":338,"max-height":434},[11,5617,5618,5620],{"id":449,"level":14},[16,5619,452],{"id":449},[20,5621,5622,5624,5626,5632,5634],{},[23,5623,457],{},[23,5625,460],{},[23,5627,463,5628],{},[20,5629,5630],{},[23,5631,468],{},[23,5633,471],{},[23,5635,474],{},[11,5637,5638,5640],{"id":477,"level":255},[16,5639,480],{"id":477},[261,5641,5642,5666],{"gap":263,"left-width":483,"right-width":483},[268,5643,5644,5646],{"v-slot:left":270},[179,5645,489],{"id":488},[20,5647,5648,5650,5658,5662],{},[23,5649,494],{},[23,5651,497,5652],{},[20,5653,5654],{},[23,5655,502,5656],{},[70,5657,505],{},[23,5659,508,5660],{},[70,5661,511],{},[23,5663,514,5664],{},[70,5665,511],{},[268,5667,5668,5670,5682],{"v-slot:right":270},[179,5669,522],{"id":521},[20,5671,5672,5676,5680],{},[23,5673,527,5674],{},[70,5675,530],{},[23,5677,533,5678],{},[70,5679,530],{},[23,5681,538],{},[540,5683],{"language":542,"src":543,"label":544},[11,5685,5686,5688],{"id":547,"level":255},[16,5687,550],{"id":547},[261,5689,5690,5711],{"gap":263,"left-width":483,"right-width":483},[268,5691,5692,5694],{"v-slot:left":270},[179,5693,558],{"id":557},[20,5695,5696,5698,5703,5705,5707,5709],{},[23,5697,563],{},[23,5699,566,5700],{},[86,5701,571],{"href":569,"rel":5702},[90],[23,5704,574],{},[23,5706,577],{},[23,5708,580],{},[23,5710,583],{},[268,5712,5713,5715,5717,5719],{"v-slot:right":270},[179,5714,589],{"id":588},[540,5716],{"language":542,"src":592,"label":593},[108,5718,596],{},[20,5720,5721,5725,5729,5733],{},[23,5722,5723,604],{},[70,5724,603],{},[23,5726,5727,609],{},[70,5728,72],{},[23,5730,612,5731],{},[70,5732,615],{},[23,5734,618,5735],{},[70,5736,621],{},[11,5738,5739,5741,5743,5745],{"id":624,"level":255},[16,5740,628],{"id":627},[108,5742,631],{},[540,5744],{"language":542,"src":634,"label":635},[20,5746,5747,5749,5751],{},[23,5748,640],{},[23,5750,643],{},[23,5752,646],{},[11,5754,5755,5757,5759,5761,5763,5765],{"id":649,"level":14},[16,5756,652],{"id":649},[108,5758,631],{},[540,5760],{"language":542,"src":657},[108,5762,660],{},[540,5764],{"language":663,"src":664},[20,5766,5767,5769,5771],{},[23,5768,669],{},[23,5770,672],{},[23,5772,675],{},[11,5774,5775,5777],{"id":678,"level":14},[16,5776,681],{"id":678},[20,5778,5779,5781,5783,5785],{},[23,5780,686],{},[23,5782,689],{},[23,5784,692],{},[23,5786,695],{},[11,5788,5789,5791],{"id":698,"level":14},[16,5790,701],{"id":698},[20,5792,5793,5795,5797,5799,5801],{},[23,5794,706],{},[23,5796,709],{},[23,5798,712],{},[23,5800,715],{},[23,5802,718,5803,721],{},[70,5804,72],{},[11,5806,5807,5809],{"id":724,"level":14},[16,5808,727],{"id":724},[261,5810,5811,5825],{"gap":263,"left-width":483,"right-width":483},[268,5812,5813,5815],{"v-slot:left":270},[179,5814,735],{"id":734},[20,5816,5817,5819,5821,5823],{},[23,5818,740],{},[23,5820,743],{},[23,5822,746],{},[23,5824,749],{},[268,5826,5827,5829],{"v-slot:right":270},[179,5828,755],{"id":754},[20,5830,5831,5836,5841],{},[23,5832,5833],{},[86,5834,764],{"href":762,"rel":5835},[90],[23,5837,5838],{},[86,5839,771],{"href":769,"rel":5840},[90],[23,5842,5843],{},[86,5844,778],{"href":776,"rel":5845},[90],[11,5847,5848,5850],{"id":781,"level":14},[16,5849,784],{"id":781},[20,5851,5852,5854,5856,5858,5866],{},[23,5853,789],{},[23,5855,792],{},[23,5857,795],{},[23,5859,798,5860],{},[20,5861,5862,5864],{},[23,5863,803],{},[23,5865,806],{},[23,5867,809],{},{"title":270,"searchDepth":424,"depth":424,"links":5869},[5870,5871,5872,5873,5874,5875,5876,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889],{"id":18,"depth":424,"text":5},{"id":34,"depth":424,"text":37},{"id":54,"depth":424,"text":57},{"id":76,"depth":424,"text":79},{"id":103,"depth":424,"text":106},{"id":143,"depth":424,"text":144},{"id":174,"depth":424,"text":177,"children":5877},[5878],{"id":181,"depth":437,"text":182},{"id":258,"depth":424,"text":259},{"id":344,"depth":424,"text":345},{"id":449,"depth":424,"text":452},{"id":477,"depth":424,"text":480},{"id":547,"depth":424,"text":550},{"id":627,"depth":424,"text":628},{"id":649,"depth":424,"text":652},{"id":678,"depth":424,"text":681},{"id":698,"depth":424,"text":701},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},{},{"title":5,"description":833},[849,850,851],{"id":5894,"title":5895,"audience":6,"body":5896,"contentType":832,"course":158,"description":6947,"estimateBasis":6948,"estimatedDiscussionMinutes":4377,"estimatedLiveMinutes":2402,"estimatedTotalMinutes":6949,"extension":838,"meta":6950,"module":840,"navigation":841,"order":6949,"path":6951,"promptAssist":844,"seo":6952,"status":846,"stem":6953,"tags":6954,"videoDuration":6955,"videoId":6956,"videoLink":6957,"videoTitle":6958,"week":840,"__hash__":6959},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository.md","Add Instructor Template To Your Repository",{"type":8,"value":5897,"toc":6919},[5898,5927,5969,5997,6030,6061,6107,6200,6244,6289,6334,6379,6451,6510,6583,6637,6713,6782,6814,6866,6890],[11,5899,5900,5902,5905],{"id":4400,"level":14},[16,5901,4403],{"id":4400},[108,5903,5904],{},"By the end, you should have:",[20,5906,5907,5910,5913,5919,5924],{},[23,5908,5909],{},"Cloned course repository open in the terminal",[23,5911,5912],{},"Starter template copied into the repository root",[23,5914,5915,5916],{},"Baseline commit on ",[70,5917,5918],{},"Module01-Course-Template",[23,5920,5921,5922],{},"Pull request merged into ",[70,5923,2593],{},[23,5925,5926],{},"Clean working tree before moving on",[11,5928,5930,5934],{"id":5929,"level":14},"step-1-open-clone",[16,5931,5933],{"id":5932},"step-1-open-the-cloned-repository","Step 1: Open The Cloned Repository",[261,5935,5936,5944],{"gap":263,"left-width":483,"right-width":483},[268,5937,5938,5940],{"v-slot:left":270},[108,5939,631],{},[540,5941],{"language":542,"src":5942,"label":5943},"\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",[268,5945,5946,5948,5951],{"v-slot:right":270},[108,5947,660],{},[540,5949],{"language":3026,"src":5950,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fopen-cloned-repository-output.txt",[20,5952,5953,5958,5963],{},[23,5954,5955,5957],{},[70,5956,1506],{},": current working directory",[23,5959,5960,5962],{},[70,5961,4647],{},": current branch and file state",[23,5964,5965,5966,5968],{},"Important check: ",[70,5967,1506],{}," ends with your repository folder",[11,5970,5972,5976,5979,5982],{"id":5971,"level":14},"step-2-open-vscode",[16,5973,5975],{"id":5974},"step-2-open-the-repository-root","Step 2: Open The Repository Root",[108,5977,5978],{},"Run from inside the cloned repository folder:",[540,5980],{"language":542,"src":5981},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-2-open-the-reposito-01.sh",[20,5983,5984,5989,5994],{},[23,5985,5986,5988],{},[70,5987,70],{},": opens VS Code from the terminal",[23,5990,5991,5993],{},[70,5992,1571],{}," means \"this current folder\"",[23,5995,5996],{},"VS Code should show your repository folder, not the parent folder",[11,5998,6000,6004],{"id":5999,"level":14},"step-3-download-template",[16,6001,6003],{"id":6002},"step-3-download-the-instructor-template","Step 3: Download The Instructor Template",[20,6005,6006,6018,6021,6024,6027],{},[23,6007,6008,6009],{},"Open the instructor template repository",[20,6010,6011],{},[23,6012,6013],{},[86,6014,6017],{"href":6015,"rel":6016},"https:\u002F\u002Fgithub.com\u002FMattToegel\u002FIT202-2026",[90],"IT202-2026",[23,6019,6020],{},"Download the ZIP",[23,6022,6023],{},"Extract the ZIP",[23,6025,6026],{},"Copy scaffold contents into your repository root",[23,6028,6029],{},"See the slide below for the copy rule",[11,6031,6033,6037,6040,6043,6058],{"id":6032,"level":255},"template-copy-rule",[179,6034,6036],{"id":6035},"copy-rule","Copy Rule",[108,6038,6039],{},"Copy the contents of the extracted template folder",[108,6041,6042],{},"Do not copy:",[20,6044,6045,6048,6055],{},[23,6046,6047],{},"The extracted wrapper folder as one extra nested folder",[23,6049,6050,6051,6054],{},"The template repository's hidden ",[70,6052,6053],{},".git"," folder",[23,6056,6057],{},"Old files from a different semester",[108,6059,6060],{},"Repository root should contain the starter folders directly",[11,6062,6064,6068,6071,6074],{"id":6063,"level":14},"step-4-check-structure",[16,6065,6067],{"id":6066},"step-4-check-the-starter-structure","Step 4: Check The Starter Structure",[108,6069,6070],{},"After copying, repository root should look similar to:",[540,6072],{"language":663,"src":6073},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-4-check-the-starter-02.txt",[20,6075,6076,6081,6090,6104],{},[23,6077,6078,6080],{},[70,6079,1637],{}," should be directly inside your repository root",[23,6082,6083,6084,6087,6088],{},"Module folders and ",[70,6085,6086],{},"project"," live inside ",[70,6089,1637],{},[23,6091,6092,236,6095,1440,6098,6101,6102],{},[70,6093,6094],{},"lib",[70,6096,6097],{},"partials",[70,6099,6100],{},"sql"," stay outside ",[70,6103,1637],{},[23,6105,6106],{},"See the slide below for the public\u002Fprivate folder boundary",[11,6108,6110,6114,6197],{"id":6109,"level":255},"public-html-boundary",[179,6111,6113],{"id":6112},"public-and-private-boundary","Public And Private Boundary",[20,6115,6116,6150,6172,6177,6182,6188,6194],{},[23,6117,6118,6120,6121],{},[70,6119,1637],{},": web root Apache can serve\n",[20,6122,6123,6133,6138,6144],{},[23,6124,6125,6128,6129,6132],{},[70,6126,6127],{},"m01"," through ",[70,6130,6131],{},"m10",": module practice folders",[23,6134,6135,6137],{},[70,6136,6086],{},": course project folder",[23,6139,6140,6143],{},[70,6141,6142],{},"index.php",": first browser entry point",[23,6145,6146,6149],{},[70,6147,6148],{},"test_db.php",": database connection check",[23,6151,6152,6154,6155],{},[70,6153,6094],{},": reusable PHP helpers\n",[20,6156,6157,6163],{},[23,6158,6159,6162],{},[70,6160,6161],{},".env.sample",": example local config file",[23,6164,6165,322,6168,6171],{},[70,6166,6167],{},"config.php",[70,6169,6170],{},"db.php",": config and database helpers",[23,6173,6174,6176],{},[70,6175,6097],{},": shared page pieces",[23,6178,6179,6181],{},[70,6180,6100],{},": database setup scripts",[23,6183,6184,6187],{},[70,6185,6186],{},"Dockerfile",": consistent runtime setup",[23,6189,6190,6193],{},[70,6191,6192],{},"structure.md",": starter layout notes",[23,6195,6196],{},"Private folders should not be opened directly in the browser",[108,6198,6199],{},"Later server setup expects this folder boundary",[11,6201,6203,6207],{"id":6202,"level":14},"step-5-check-status",[16,6204,6206],{"id":6205},"step-5-create-the-template-branch","Step 5: Create The Template Branch",[261,6208,6209,6217],{"gap":263,"left-width":483,"right-width":483},[268,6210,6211,6213],{"v-slot:left":270},[108,6212,631],{},[540,6214],{"language":542,"src":6215,"label":6216},"\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",[268,6218,6219,6222,6225],{"v-slot:right":270},[108,6220,6221],{},"Expected idea:",[540,6223],{"language":663,"src":6224,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-template-copy.txt",[20,6226,6227,6233,6238,6241],{},[23,6228,6229,6232],{},[70,6230,6231],{},"git checkout -b",": create and move to a new branch",[23,6234,6235,6236],{},"Branch name: ",[70,6237,5918],{},[23,6239,6240],{},"New files listed as untracked",[23,6242,6243],{},"No changes means likely wrong folder or copy missed",[11,6245,6247,6251],{"id":6246,"level":14},"step-6-stage",[16,6248,6250],{"id":6249},"step-6-stage-the-baseline-files","Step 6: Stage The Baseline Files",[261,6252,6253,6261],{"gap":263,"left-width":483,"right-width":483},[268,6254,6255,6257],{"v-slot:left":270},[108,6256,631],{},[540,6258],{"language":542,"src":6259,"label":6260},"\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",[268,6262,6263,6266,6284,6286],{"v-slot:right":270},[108,6264,6265],{},"What this means:",[20,6267,6268,6274,6279],{},[23,6269,6270,6273],{},[70,6271,6272],{},"git add",": choose files for the next commit",[23,6275,6276,6278],{},[70,6277,1571],{}," means current folder and contents",[23,6280,6281,6283],{},[70,6282,4647],{},": verify what is staged before committing",[108,6285,6221],{},[540,6287],{"language":663,"src":6288,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstatus-after-stage.txt",[11,6290,6292,6296],{"id":6291,"level":14},"step-7-commit",[16,6293,6295],{"id":6294},"step-7-commit-the-baseline","Step 7: Commit The Baseline",[261,6297,6298,6306],{"gap":263,"left-width":483,"right-width":483},[268,6299,6300,6302],{"v-slot:left":270},[108,6301,631],{},[540,6303],{"language":542,"src":6304,"label":6305},"\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",[268,6307,6308,6310,6313],{"v-slot:right":270},[108,6309,6221],{},[540,6311],{"language":663,"src":6312,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fcommit-baseline-output.txt",[20,6314,6315,6321,6331],{},[23,6316,6317,6320],{},[70,6318,6319],{},"git commit",": save staged changes in local history",[23,6322,6323,6325,6326],{},[70,6324,4745],{},": commit message\n",[20,6327,6328],{},[23,6329,6330],{},"Message is required, even if empty",[23,6332,6333],{},"Baseline commit: starter state before custom work",[11,6335,6337,6341],{"id":6336,"level":14},"step-8-push",[16,6338,6340],{"id":6339},"step-8-push-the-template-branch","Step 8: Push The Template Branch",[261,6342,6343,6351],{"gap":263,"left-width":483,"right-width":483},[268,6344,6345,6347],{"v-slot:left":270},[108,6346,631],{},[540,6348],{"language":542,"src":6349,"label":6350},"\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",[268,6352,6353,6355,6358],{"v-slot:right":270},[108,6354,6221],{},[540,6356],{"language":663,"src":6357,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpush-baseline-output.txt",[20,6359,6360,6365,6371,6376],{},[23,6361,6362,6364],{},[70,6363,4808],{},": GitHub remote",[23,6366,6367,6370],{},[70,6368,6369],{},"-u",": remembers this branch's GitHub tracking branch",[23,6372,6373,6375],{},[70,6374,5918],{},": branch being sent",[23,6377,6378],{},"Refresh GitHub after the push",[11,6380,6382,6386],{"id":6381,"level":14},"step-9-open-pull-request",[16,6383,6385],{"id":6384},"step-9-open-the-pull-request","Step 9: Open The Pull Request",[261,6387,6388,6431],{"gap":263,"left-width":483,"right-width":483},[268,6389,6390,6392],{"v-slot:left":270},[108,6391,3464],{},[20,6393,6394,6397,6413,6418,6423,6426],{},[23,6395,6396],{},"Open your course repository",[23,6398,1004,6399,6402],{},[963,6400,6401],{},"Compare & pull request",[20,6403,6404],{},[23,6405,6406,6407,119,6410],{},"Or use ",[963,6408,6409],{},"Pull requests",[963,6411,6412],{},"New pull request",[23,6414,6415,6416],{},"Set base branch to ",[70,6417,2593],{},[23,6419,6420,6421],{},"Set compare branch to ",[70,6422,5918],{},[23,6424,6425],{},"Confirm the changed files are the starter template files",[23,6427,1004,6428],{},[963,6429,6430],{},"Create pull request",[268,6432,6433,6436,6440],{"v-slot:right":270},[108,6434,6435],{},"Use a short title and description:",[540,6437],{"language":663,"src":6438,"label":6439},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fpull-request-description.txt","pull-request-description.txt",[20,6441,6442,6445,6448],{},[23,6443,6444],{},"Base receives the changes",[23,6446,6447],{},"Compare contains your branch work",[23,6449,6450],{},"If base and compare are reversed, do not create the pull request",[11,6452,6454,6460],{"id":6453,"level":14},"step-10-merge-sync-main",[16,6455,6457,6458],{"id":6456},"step-10-merge-and-sync-main","Step 10: Merge And Sync ",[70,6459,2593],{},[261,6461,6462,6484],{"gap":263,"left-width":483,"right-width":483},[268,6463,6464,6466,6478,6480],{"v-slot:left":270},[108,6465,3464],{},[20,6467,6468,6473],{},[23,6469,1004,6470],{},[963,6471,6472],{},"Merge pull request",[23,6474,1004,6475],{},[963,6476,6477],{},"Confirm merge",[108,6479,5102],{},[540,6481],{"language":542,"src":6482,"label":6483},"\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",[268,6485,6486,6488,6491],{"v-slot:right":270},[108,6487,6221],{},[540,6489],{"language":663,"src":6490,"label":3409},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fsync-main-after-pr-output.txt",[20,6492,6493,6499,6505],{},[23,6494,6495,6498],{},[70,6496,6497],{},"git checkout main",": return to the main branch",[23,6500,6501,6504],{},[70,6502,6503],{},"git pull origin main",": download the merged template files",[23,6506,6507,6508,5126],{},"Continue only when local ",[70,6509,2593],{},[11,6511,6513,6519],{"id":6512,"level":14},"step-11-create-local-env",[16,6514,6515,6516],{"id":6512},"Step 11: Create Local ",[70,6517,6518],{},".env",[261,6520,6521,6543],{"gap":263,"left-width":483,"right-width":483},[268,6522,6523,6526,6530],{"v-slot:left":270},[108,6524,6525],{},"Run from the repository root:",[540,6527],{"language":542,"src":6528,"label":6529},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fstep-11-create-local-env-11.sh","create-local-env.sh",[20,6531,6532],{},[23,6533,6534,6535,6538,6539],{},"Get ",[70,6536,6537],{},"DB_URL"," from ",[86,6540,6542],{"href":313,"rel":6541},[90],"courses.ethereallab.app\u002Fdatabase",[268,6544,6545,6548,6553],{"v-slot:right":270},[108,6546,6547],{},"Fill in values similar to:",[540,6549],{"language":6550,"src":6551,"label":6552},"dotenv","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Flocal-env-example.txt","lib\u002F.env",[20,6554,6555,6560,6565,6568,6573,6578],{},[23,6556,6557,6559],{},[70,6558,6518],{}," stores local secrets",[23,6561,2527,6562,6564],{},[70,6563,6518],{}," on your computer only",[23,6566,6567],{},"Do not commit your real connection string",[23,6569,6570,6571],{},"Paste the generated database connection string as ",[70,6572,6537],{},[23,6574,6575,6577],{},[70,6576,6167],{}," loads local or hosted environment variables",[23,6579,6580,6581],{},"Do not paste secrets directly into ",[70,6582,6167],{},[11,6584,6586,6590],{"id":6585,"level":14},"step-12-test-local-db",[16,6587,6589],{"id":6588},"step-12-test-local-database-connection","Step 12: Test Local Database Connection",[261,6591,6592,6600],{"gap":263,"left-width":483,"right-width":483},[268,6593,6594,6596],{"v-slot:left":270},[108,6595,6525],{},[540,6597],{"language":542,"src":6598,"label":6599},"\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",[268,6601,6602,6605,6609],{"v-slot:right":270},[108,6603,6604],{},"Then open:",[540,6606],{"language":663,"src":6607,"label":6608},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Ftest-db-url.txt","browser-url.txt",[20,6610,6611,6617,6623,6631],{},[23,6612,6613,6616],{},[70,6614,6615],{},"php -S",": starts PHP's built-in local server",[23,6618,6619,6622],{},[70,6620,6621],{},"-t public_html",": serves the course web root",[23,6624,6625,6627,6628,6630],{},[70,6626,6148],{},": confirms PHP can read ",[70,6629,6518],{}," and connect to MySQL",[23,6632,6633,6634,6636],{},"Stop the server with ",[70,6635,2234],{}," when finished",[11,6638,6640,6648,6654],{"id":6639,"level":14},"step-13-enable-pdo-mysql",[16,6641,6643,6644,6647],{"id":6642},"step-13-enable-pdo_mysql-if-needed","Step 13: Enable ",[70,6645,6646],{},"pdo_mysql"," If Needed",[108,6649,6650,6651,1571],{},"This is usually a Windows PHP ZIP setup issue. macOS and Linux usually install MySQL support through Homebrew or ",[70,6652,6653],{},"apt",[261,6655,6656,6687],{"gap":263,"left-width":483,"right-width":483},[268,6657,6658,6661,6665,6668],{"v-slot:left":270},[108,6659,6660],{},"Find the PHP folder:",[540,6662],{"language":542,"src":6663,"label":6664},"\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",[108,6666,6667],{},"In that folder:",[20,6669,6670,6676,6682],{},[23,6671,6672,6673],{},"Find ",[70,6674,6675],{},"php.ini-development",[23,6677,6678,6679],{},"Copy it as ",[70,6680,6681],{},"php.ini",[23,6683,3846,6684,6686],{},[70,6685,6681],{}," in your editor",[268,6688,6689,6692,6696,6699,6703],{"v-slot:right":270},[108,6690,6691],{},"Uncomment these lines:",[540,6693],{"language":6694,"src":6695,"label":6681},"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",[108,6697,6698],{},"Mac\u002FLinux usually use:",[540,6700],{"language":542,"src":6701,"label":6702},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fmacos-linux-pdo-mysql-commands-14.sh","macos-linux-php-mysql.sh",[20,6704,6705,6710],{},[23,6706,6707,6708],{},"Restart the php dev server after changing ",[70,6709,6681],{},[23,6711,6712],{},"Run Step 12 again after enabling the extension",[11,6714,6716,6718,6721],{"id":6715,"level":14},"quick-check-final",[16,6717,701],{"id":698},[108,6719,6720],{},"Confirm all of these:",[20,6722,6723,6726,6734,6737,6742,6751,6757,6762,6767,6773],{},[23,6724,6725],{},"GitHub shows the starter files",[23,6727,6728,6729,6731,6732],{},"GitHub shows a pull request from ",[70,6730,5918],{}," into ",[70,6733,2593],{},[23,6735,6736],{},"The pull request is merged",[23,6738,4872,6739,6741],{},[70,6740,2593],{}," says the working tree is clean",[23,6743,6744,6128,6747,6750],{},[70,6745,6746],{},"public_html\u002Fm01",[70,6748,6749],{},"public_html\u002Fm10"," exist",[23,6752,6753,6756],{},[70,6754,6755],{},"public_html\u002Fproject"," exists",[23,6758,6759,6761],{},[70,6760,1637],{}," is not nested inside another accidental folder",[23,6763,6764,6766],{},[70,6765,6552],{}," exists locally and is not committed with real secrets",[23,6768,6769,6772],{},[70,6770,6771],{},"http:\u002F\u002Flocalhost:3000\u002Ftest_db.php"," confirms the database connection",[23,6774,6775,6776,6778,6779,6781],{},"Windows PHP has ",[70,6777,6646],{}," enabled if ",[70,6780,6148],{}," reports a missing driver",[11,6783,6785,6789,6791,6794,6803],{"id":6784,"level":14},"reset-check",[16,6786,6788],{"id":6787},"if-something-looks-wrong","If Something Looks Wrong",[108,6790,631],{},[540,6792],{"language":542,"src":6793},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository\u002Fif-something-looks-wrong-03.sh",[6795,6796,6797],"blockquote",{},[108,6798,6799,6800,6802],{},"Tip: ",[70,6801,4000],{}," prints the repository root when your current folder is inside a Git repository",[20,6804,6805,6808,6811],{},[23,6806,6807],{},"Output should point to your course repository",[23,6809,6810],{},"If it points somewhere else, move folders before continuing",[23,6812,6813],{},"Avoid cloning inside another cloned repository",[11,6815,6816,6818],{"id":678,"level":14},[16,6817,681],{"id":678},[20,6819,6820,6823,6826,6831,6834,6837,6842,6852,6857,6860],{},[23,6821,6822],{},"Opening the parent folder instead of the repository root",[23,6824,6825],{},"Copying the instructor template folder as a nested folder",[23,6827,6828,6829,6054],{},"Copying the template ",[70,6830,6053],{},[23,6832,6833],{},"Keeping the downloaded ZIP inside the repository",[23,6835,6836],{},"Re-cloning the repository instead of opening the existing clone",[23,6838,6839,6840],{},"Putting module folders outside ",[70,6841,1637],{},[23,6843,6844,6845,6847,6848,6851],{},"Renaming ",[70,6846,6127],{}," to ",[70,6849,6850],{},"M1"," or mixing folder casing",[23,6853,6854,6855],{},"Doing template work directly on ",[70,6856,2593],{},[23,6858,6859],{},"Reversing base and compare branches in the pull request",[23,6861,6862,6863,6865],{},"Forgetting to sync local ",[70,6864,2593],{}," after the pull request is merged",[11,6867,6868,6870],{"id":734,"level":14},[16,6869,735],{"id":734},[20,6871,6872,6875,6878,6881,6884,6887],{},[23,6873,6874],{},"Repository root: top folder of the cloned project",[23,6876,6877],{},"Baseline: starter state before custom work begins",[23,6879,6880],{},"Pull request: GitHub review page used to merge branch work",[23,6882,6883],{},"Web root: folder served to the browser",[23,6885,6886],{},"Scaffold: starter folders that organize future work",[23,6888,6889],{},"Staging: choosing files for the next commit",[11,6891,6892,6894,6897],{"id":781,"level":14},[16,6893,784],{"id":781},[108,6895,6896],{},"Before leaving this presentation, confirm the following:",[20,6898,6899,6902,6905,6908,6914],{},[23,6900,6901],{},"You still have one clone for your repository",[23,6903,6904],{},"Your VS Code is able to open directly to your repository",[23,6906,6907],{},"Your repository has the full starter baseline correctly structured",[23,6909,6910,6911,6913],{},"GitHub remote ",[70,6912,2593],{}," has the baseline content",[23,6915,4872,6916,6918],{},[70,6917,2593],{}," was synchronized",{"title":270,"searchDepth":424,"depth":424,"links":6920},[6921,6922,6923,6924,6927,6930,6931,6932,6933,6934,6935,6937,6939,6940,6942,6943,6944,6945,6946],{"id":4400,"depth":424,"text":4403},{"id":5932,"depth":424,"text":5933},{"id":5974,"depth":424,"text":5975},{"id":6002,"depth":424,"text":6003,"children":6925},[6926],{"id":6035,"depth":437,"text":6036},{"id":6066,"depth":424,"text":6067,"children":6928},[6929],{"id":6112,"depth":437,"text":6113},{"id":6205,"depth":424,"text":6206},{"id":6249,"depth":424,"text":6250},{"id":6294,"depth":424,"text":6295},{"id":6339,"depth":424,"text":6340},{"id":6384,"depth":424,"text":6385},{"id":6456,"depth":424,"text":6936},"Step 10: Merge And Sync main",{"id":6512,"depth":424,"text":6938},"Step 11: Create Local .env",{"id":6588,"depth":424,"text":6589},{"id":6642,"depth":424,"text":6941},"Step 13: Enable pdo_mysql If Needed",{"id":698,"depth":424,"text":701},{"id":6787,"depth":424,"text":6788},{"id":678,"depth":424,"text":681},{"id":734,"depth":424,"text":735},{"id":781,"depth":424,"text":784},"Continue from your cloned course repository, copy in the instructor template, and merge the baseline files through a pull request.","Face-to-face class of about 40 students; starts from an existing clone and includes template copy checks, ZIP extraction, first commit verification, and common folder mistakes.","60",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",{"title":5895,"description":6947},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F06-add-instructor-template-to-your-repository",[4387,268,2628],"47:11","4n0-QuXO_Aw","https:\u002F\u002Fyoutu.be\u002F4n0-QuXO_Aw","Adding Instructor\u002FCourse Template","iYq9WdND1ODBRrXLU2gX9dNCXvDc-Kvqufsokl_jg3E",{"id":6961,"title":6962,"audience":6,"body":6963,"contentType":832,"course":158,"description":7673,"estimateBasis":7674,"estimatedDiscussionMinutes":4377,"estimatedLiveMinutes":837,"estimatedTotalMinutes":2403,"extension":838,"meta":7675,"module":840,"navigation":841,"order":4378,"path":7676,"promptAssist":844,"seo":7677,"status":846,"stem":7678,"tags":7679,"videoDuration":7681,"videoId":7682,"videoLink":7683,"videoTitle":7684,"week":840,"__hash__":7685},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches.md","QA And Prod Branches",{"type":8,"value":6964,"toc":7652},[6965,6999,7047,7069,7123,7188,7246,7296,7361,7402,7494,7534,7561,7619],[11,6966,6967,6969,6971],{"id":4400,"level":14},[16,6968,4403],{"id":4400},[108,6970,4406],{},[20,6972,6973,6982,6987,6991,6996],{},[23,6974,6975,6976,322,6979],{},"Understand the purpose and usage of ",[70,6977,6978],{},"qa",[70,6980,6981],{},"prod",[23,6983,6984,6985],{},"Create and push ",[70,6986,6978],{},[23,6988,6984,6989],{},[70,6990,6981],{},[23,6992,6993,6994],{},"Keep local work pointed at ",[70,6995,6978],{},[23,6997,6998],{},"Confirm GitHub has the expected branches",[11,7000,7002,7005,7040],{"id":7001,"level":14},"branch-roles",[16,7003,7004],{"id":7001},"Branch Roles",[20,7006,7007,7017,7027,7037],{},[23,7008,7009,7011,7012],{},[70,7010,2593],{},": starter baseline and shared source branch\n",[20,7013,7014],{},[23,7015,7016],{},"Most projects stick with this; we'll split ours into development lanes",[23,7018,7019,7021,7022],{},[70,7020,6978],{},": public testing and evidence branch\n",[20,7023,7024],{},[23,7025,7026],{},"Normal branch to return to before new course work",[23,7028,7029,7031,7032],{},[70,7030,6981],{},": stable grading and evaluation branch\n",[20,7033,7034],{},[23,7035,7036],{},"Protected from everyday local edits",[23,7038,7039],{},"Later deployment setup connects Render to these branches",[108,7041,7042,7043,119,7045],{},"Course flow: feature or homework branch -> ",[70,7044,6978],{},[70,7046,6981],{},[11,7048,7049,7051,7054,7058],{"id":1452,"level":14},[16,7050,1455],{"id":1452},[108,7052,7053],{},"Run inside the course repository:",[540,7055],{"label":7056,"language":542,"src":7057},"before-you-start.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fbefore-you-start.sh",[20,7059,7060,7063,7066],{},[23,7061,7062],{},"Working tree should be clean",[23,7064,7065],{},"Starter baseline already pushed to GitHub",[23,7067,7068],{},"Stop if Git says files are modified or untracked",[11,7070,7072,7078],{"id":7071,"level":14},"step-1-sync-main",[16,7073,7075,7076],{"id":7074},"step-1-start-from-main","Step 1: Start From ",[70,7077,2593],{},[261,7079,7080,7088],{"gap":263,"left-width":483,"right-width":483},[268,7081,7082,7084],{"v-slot:left":270},[108,7083,631],{},[540,7085],{"label":7086,"language":542,"src":7087},"sync-main.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main.sh",[268,7089,7090,7092,7095],{"v-slot:right":270},[108,7091,660],{},[540,7093],{"label":3409,"language":663,"src":7094},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fsync-main-output.txt",[20,7096,7097,7104],{},[23,7098,7099,7101,7102],{},[70,7100,6497],{},": switch to ",[70,7103,2593],{},[23,7105,7106,7108,7109,7111,7112],{},[70,7107,6503],{},": get the latest ",[70,7110,2593],{}," from GitHub\n",[20,7113,7114,7118],{},[23,7115,7116,6364],{},[70,7117,4808],{},[23,7119,7120,7122],{},[70,7121,2593],{},": remote branch being pulled",[11,7124,7126,7132],{"id":7125,"level":14},"step-2-create-qa",[16,7127,7129,7130],{"id":7128},"step-2-create-and-push-qa","Step 2: Create And Push ",[70,7131,6978],{},[261,7133,7134,7142],{"gap":263,"left-width":483,"right-width":483},[268,7135,7136,7138],{"v-slot:left":270},[108,7137,631],{},[540,7139],{"label":7140,"language":542,"src":7141},"create-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa.sh",[268,7143,7144,7146,7149],{"v-slot:right":270},[108,7145,660],{},[540,7147],{"label":3409,"language":663,"src":7148},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-qa-output.txt",[20,7150,7151,7168],{},[23,7152,7153,7156,7157,7159,7160],{},[70,7154,7155],{},"git checkout -b qa",": create ",[70,7158,6978],{}," and switch to it\n",[20,7161,7162],{},[23,7163,7164,7167],{},[70,7165,7166],{},"-b",": creates a new branch of the following name",[23,7169,7170,7173,7174,7176,7177],{},[70,7171,7172],{},"git push -u origin qa",": send ",[70,7175,6978],{}," to GitHub\n",[20,7178,7179],{},[23,7180,7181,7183,7184,7187],{},[70,7182,6369],{},": remember ",[70,7185,7186],{},"origin\u002Fqa"," as the upstream branch",[11,7189,7191,7197],{"id":7190,"level":14},"step-3-create-prod",[16,7192,7194,7195],{"id":7193},"step-3-create-and-push-prod","Step 3: Create And Push ",[70,7196,6981],{},[261,7198,7199,7207],{"gap":263,"left-width":483,"right-width":483},[268,7200,7201,7203],{"v-slot:left":270},[108,7202,631],{},[540,7204],{"label":7205,"language":542,"src":7206},"create-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod.sh",[268,7208,7209,7211,7214],{"v-slot:right":270},[108,7210,660],{},[540,7212],{"label":3409,"language":663,"src":7213},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fcreate-prod-output.txt",[20,7215,7216,7224,7229,7241],{},[23,7217,155,7218,7220,7221,7223],{},[70,7219,6981],{}," from the current ",[70,7222,6978],{}," branch",[23,7225,7226],{},[70,7227,7228],{},"git checkout -b prod",[23,7230,7231,7232,7176,7234],{},"Push ",[70,7233,6981],{},[20,7235,7236],{},[23,7237,7238],{},[70,7239,7240],{},"git push origin prod",[23,7242,7243,7245],{},[70,7244,6981],{}," starts from the same clean baseline",[11,7247,7249,7254],{"id":7248,"level":14},"step-4-return-to-qa",[16,7250,7251,7252],{"id":7248},"Step 4: Return To ",[70,7253,6978],{},[261,7255,7256,7264],{"gap":263,"left-width":483,"right-width":483},[268,7257,7258,7260],{"v-slot:left":270},[108,7259,631],{},[540,7261],{"label":7262,"language":542,"src":7263},"return-to-qa.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa.sh",[268,7265,7266,7268,7271],{"v-slot:right":270},[108,7267,660],{},[540,7269],{"label":3409,"language":663,"src":7270},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Freturn-to-qa-output.txt",[20,7272,7273,7278,7283],{},[23,7274,7275,7277],{},[70,7276,6978],{}," should have the asterisk",[23,7279,7280,7282],{},[70,7281,6981],{}," should still exist on GitHub",[23,7284,7285,7286,7288],{},"Do not start normal course work from ",[70,7287,6981],{},[20,7289,7290],{},[23,7291,7292,7293,7295],{},"We'll remove local ",[70,7294,6981],{}," to avoid this issue",[11,7297,7299,7305],{"id":7298,"level":14},"step-5-delete-local-prod",[16,7300,7302,7303],{"id":7301},"step-5-remove-local-prod","Step 5: Remove Local ",[70,7304,6981],{},[261,7306,7307,7315],{"gap":263,"left-width":483,"right-width":483},[268,7308,7309,7311],{"v-slot:left":270},[108,7310,631],{},[540,7312],{"label":7313,"language":542,"src":7314},"delete-local-prod.sh","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod.sh",[268,7316,7317,7319,7322],{"v-slot:right":270},[108,7318,660],{},[540,7320],{"label":3409,"language":663,"src":7321},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches\u002Fdelete-local-prod-output.txt",[20,7323,7324,7346],{},[23,7325,7326,7329,7330,7332],{},[70,7327,7328],{},"git branch -d prod",": delete local ",[70,7331,6981],{},[20,7333,7334,7340],{},[23,7335,7336,7339],{},[70,7337,7338],{},"-d",": delete only if Git considers it safe",[23,7341,7342,7345],{},[70,7343,7344],{},"-D",": can be used as a forced delete",[23,7347,7348,7351,7352],{},[70,7349,7350],{},"git branch -r",": list remote branches\n",[20,7353,7354],{},[23,7355,7356,7357,7360],{},"Confirms ",[70,7358,7359],{},"origin\u002Fprod"," still exists",[11,7362,7364,7367,7370,7373,7387,7390],{"id":7363,"level":14},"github-check",[16,7365,7366],{"id":7363},"GitHub Check",[108,7368,7369],{},"Open the branch dropdown on GitHub",[108,7371,7372],{},"You should see:",[20,7374,7375,7379,7383],{},[23,7376,7377],{},[70,7378,2593],{},[23,7380,7381],{},[70,7382,6978],{},[23,7384,7385],{},[70,7386,6981],{},[108,7388,7389],{},"Branch roles:",[20,7391,7392,7397],{},[23,7393,7394,7396],{},[70,7395,6978],{},": testing and evidence",[23,7398,7399,7401],{},[70,7400,6981],{},": stable grading target",[11,7403,7405,7409],{"id":7404,"level":14},"normal-workflow",[16,7406,7408],{"id":7407},"normal-workflow-after-setup","Normal Workflow After Setup",[410,7410,7411,7428,7436,7447,7452,7466,7469,7476,7488],{},[23,7412,7413,7414,7416],{},"Return to ",[70,7415,6978],{},[20,7417,7418,7423],{},[23,7419,7420],{},[70,7421,7422],{},"git checkout qa",[23,7424,7425],{},[70,7426,7427],{},"git pull origin qa",[23,7429,7430,7431],{},"Create a feature or homework branch\n",[20,7432,7433],{},[23,7434,7435],{},"Branch name matches the task",[23,7437,7438,7439],{},"Commit the work on that branch\n",[20,7440,7441],{},[23,7442,7443,7444,7446],{},"Check ",[70,7445,4647],{}," before each Git command",[23,7448,7449,7450],{},"Push the branch and open a pull request into ",[70,7451,6978],{},[23,7453,7454,7455,7457,7458],{},"Merge into ",[70,7456,6978],{}," after review\n",[20,7459,7460],{},[23,7461,7462,7463,7465],{},"QA deployment will update from ",[70,7464,6978],{}," after Render setup",[23,7467,7468],{},"Test the QA version",[23,7470,7471,7472,6731,7474],{},"Open a pull request from ",[70,7473,6978],{},[70,7475,6981],{},[23,7477,7454,7478,7480,7481],{},[70,7479,6981],{}," when stable\n",[20,7482,7483],{},[23,7484,7485,7486,7465],{},"Production deployment will use ",[70,7487,6981],{},[23,7489,7490,7491,7493],{},"Return locally to ",[70,7492,6978],{}," and pull before the next task",[11,7495,7496,7498],{"id":678,"level":14},[16,7497,681],{"id":678},[20,7499,7500,7505,7510,7518,7526,7529],{},[23,7501,7502,7503],{},"Working directly on ",[70,7504,6981],{},[23,7506,7507,7508],{},"Forgetting to return to ",[70,7509,6978],{},[23,7511,7512,7513,7515,7516],{},"Pushing ",[70,7514,6978],{}," but not ",[70,7517,6981],{},[23,7519,7520,7521,7523,7524],{},"Deleting remote ",[70,7522,6981],{}," instead of local ",[70,7525,6981],{},[23,7527,7528],{},"Assuming GitHub has the branch without checking",[23,7530,7531,7532,5126],{},"Starting new work before ",[70,7533,4647],{},[11,7535,7536,7538,7541],{"id":698,"level":14},[16,7537,701],{"id":698},[108,7539,7540],{},"Answer before moving on:",[20,7542,7543,7546,7549,7552,7558],{},[23,7544,7545],{},"Which branch should QA deployment watch?",[23,7547,7548],{},"Which branch should production grading use?",[23,7550,7551],{},"Which branch should you return to before new work?",[23,7553,7554,7555,7557],{},"Why remove local ",[70,7556,6981],{}," after pushing it?",[23,7559,7560],{},"What future setup connects Render to these branches?",[11,7562,7563,7565],{"id":754,"level":14},[16,7564,727],{"id":724},[261,7566,7567,7592],{"gap":263,"left-width":483,"right-width":483},[268,7568,7569,7571],{"v-slot:left":270},[179,7570,735],{"id":734},[20,7572,7573,7576,7579,7584,7589],{},[23,7574,7575],{},"Branch: named line of Git history",[23,7577,7578],{},"Upstream: remote branch Git remembers for push\u002Fpull",[23,7580,7581,7583],{},[70,7582,6978],{},": public testing branch",[23,7585,7586,7588],{},[70,7587,6981],{},": stable grading branch",[23,7590,7591],{},"Remote-only branch: exists on GitHub, not locally",[268,7593,7594,7596],{"v-slot:right":270},[179,7595,755],{"id":754},[20,7597,7598,7605,7612],{},[23,7599,5221,7600],{},[86,7601,7604],{"href":7602,"rel":7603},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fget-started\u002Fusing-git\u002Fabout-git#about-branches",[90],"About branches",[23,7606,5221,7607],{},[86,7608,7611],{"href":7609,"rel":7610},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpull-requests\u002Fcollaborating-with-pull-requests\u002Fproposing-changes-to-your-work-with-pull-requests\u002Fabout-pull-requests",[90],"About pull requests",[23,7613,5206,7614],{},[86,7615,7618],{"href":7616,"rel":7617},"https:\u002F\u002Fgit-scm.com\u002Fbook\u002Fen\u002Fv2\u002FGit-Branching-Branches-in-a-Nutshell",[90],"Git Branching",[11,7620,7621,7623,7625],{"id":781,"level":14},[16,7622,784],{"id":781},[108,7624,2325],{},[20,7626,7627,7636,7640,7644,7649],{},[23,7628,7629,7630,236,7632,1440,7634],{},"Explain ",[70,7631,2593],{},[70,7633,6978],{},[70,7635,6981],{},[23,7637,6984,7638],{},[70,7639,6978],{},[23,7641,6984,7642],{},[70,7643,6981],{},[23,7645,7646,7647],{},"Keep local work branched from ",[70,7648,6978],{},[23,7650,7651],{},"Verify remote branches on GitHub",{"title":270,"searchDepth":424,"depth":424,"links":7653},[7654,7655,7656,7657,7659,7661,7663,7665,7667,7668,7669,7670,7671,7672],{"id":4400,"depth":424,"text":4403},{"id":7001,"depth":424,"text":7004},{"id":1452,"depth":424,"text":1455},{"id":7074,"depth":424,"text":7658},"Step 1: Start From main",{"id":7128,"depth":424,"text":7660},"Step 2: Create And Push qa",{"id":7193,"depth":424,"text":7662},"Step 3: Create And Push prod",{"id":7248,"depth":424,"text":7664},"Step 4: Return To qa",{"id":7301,"depth":424,"text":7666},"Step 5: Remove Local prod",{"id":7363,"depth":424,"text":7366},{"id":7407,"depth":424,"text":7408},{"id":678,"depth":424,"text":681},{"id":698,"depth":424,"text":701},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"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":6962,"description":7673},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F07-qa-prod-branches",[2628,5323,6978,7680],"production","10:35","32XilHQwRiY","https:\u002F\u002Fyoutu.be\u002F32XilHQwRiY","Create QA and Prod Branches","GZx1sXtI0BMbyb6Gbpj7aoBvczhhR-FV7YpFE4j4UCs",{"id":7687,"title":7688,"audience":6,"body":7689,"contentType":832,"course":158,"description":8496,"estimateBasis":8497,"estimatedDiscussionMinutes":4377,"estimatedLiveMinutes":2403,"estimatedTotalMinutes":4378,"extension":838,"meta":8498,"module":840,"navigation":841,"order":8499,"path":8500,"promptAssist":844,"seo":8501,"status":846,"stem":8502,"tags":8503,"videoDuration":8506,"videoId":8507,"videoLink":8508,"videoTitle":8509,"week":840,"__hash__":8510},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup.md","Render Setup",{"type":8,"value":7690,"toc":8475},[7691,7718,7741,7770,7838,7899,7934,7970,8007,8057,8103,8138,8184,8221,8249,8281,8328,8361,8429],[11,7692,7694,7697],{"id":7693,"level":14},"render-setup-title",[16,7695,7688],{"id":7696},"render-setup",[20,7698,7699,7702,7707,7712,7715],{},[23,7700,7701],{},"Connect GitHub repo to Render",[23,7703,7704,7705],{},"Create a QA service from ",[70,7706,6978],{},[23,7708,7709,7710],{},"Create a production service from ",[70,7711,6981],{},[23,7713,7714],{},"Add the course database connection string",[23,7716,7717],{},"Verify live URLs and deploy logs",[11,7719,7720,7722,7724],{"id":3307,"level":14},[16,7721,3310],{"id":3307},[108,7723,4406],{},[20,7725,7726,7729,7732,7735,7738],{},[23,7727,7728],{},"Explain what Render does in the course workflow",[23,7730,7731],{},"Create separate QA and production services",[23,7733,7734],{},"Connect each service to the correct branch",[23,7736,7737],{},"Read Render logs when a deploy fails",[23,7739,7740],{},"Identify which deployed URL to submit or test",[11,7742,7744,7747,7764],{"id":7743,"level":14},"what-render-does",[16,7745,7746],{"id":7743},"What Render Does",[20,7748,7749,7752,7755,7758,7761],{},[23,7750,7751],{},"Hosts your PHP app from GitHub",[23,7753,7754],{},"Watches a selected branch",[23,7756,7757],{},"Rebuilds when that branch changes",[23,7759,7760],{},"Stores secrets as environment variables",[23,7762,7763],{},"Gives each service a public URL",[108,7765,7766,7767],{},"Course loop: ",[70,7768,7769],{},"local work -> GitHub branch -> Render URL",[11,7771,7773,7775],{"id":7772,"level":14},"free-tier-and-before-start",[16,7774,1455],{"id":1452},[261,7776,7777,7806],{"gap":263,"left-width":483,"right-width":483},[268,7778,7779,7783],{"v-slot:left":270},[179,7780,7782],{"id":7781},"free-tier","Free Tier",[20,7784,7785,7795,7803],{},[23,7786,3474,7787,7790],{},[70,7788,7789],{},"Free",[20,7791,7792],{},[23,7793,7794],{},"Render may default to a paid plan",[23,7796,7797,7798],{},"Free services can sleep",[20,7799,7800],{},[23,7801,7802],{},"First visit after sleep may be slow",[23,7804,7805],{},"Avoid extra services unless instructed",[268,7807,7808,7812],{"v-slot:right":270},[179,7809,7811],{"id":7810},"repo-ready","Repo Ready",[20,7813,7814,7817,7822,7831],{},[23,7815,7816],{},"Starter files committed and pushed",[23,7818,7819,7821],{},[70,7820,6186],{}," in repo root",[23,7823,7824,236,7826,1440,7828,7830],{},[70,7825,1637],{},[70,7827,6094],{},[70,7829,6097],{}," present",[23,7832,7833,322,7835,7837],{},[70,7834,6978],{},[70,7836,6981],{}," branches exist on GitHub",[11,7839,7841,7844],{"id":7840,"level":14},"target-architecture",[16,7842,7843],{"id":7840},"Target Architecture",[261,7845,7846,7874],{"gap":263,"left-width":483,"right-width":483},[268,7847,7848,7852],{"v-slot:left":270},[179,7849,7851],{"id":7850},"qa-service","QA Service",[20,7853,7854,7860,7865,7868],{},[23,7855,7856,7857],{},"Name: ",[70,7858,7859],{},"\u003Cucid>-it202-\u003Csection>-qa",[23,7861,7862,7863],{},"Watches ",[70,7864,6978],{},[23,7866,7867],{},"Used for testing and evidence",[23,7869,7870,7871],{},"URL ends with ",[70,7872,7873],{},"-qa.onrender.com",[268,7875,7876,7880],{"v-slot:right":270},[179,7877,7879],{"id":7878},"production-service","Production Service",[20,7881,7882,7887,7891,7894],{},[23,7883,7856,7884],{},[70,7885,7886],{},"\u003Cucid>-it202-\u003Csection>-prod",[23,7888,7862,7889],{},[70,7890,6981],{},[23,7892,7893],{},"Stable version after QA checks",[23,7895,7870,7896],{},[70,7897,7898],{},"-prod.onrender.com",[11,7900,7902,7906],{"id":7901,"level":14},"step-1-sign-up",[16,7903,7905],{"id":7904},"step-1-sign-up-with-github","Step 1: Sign Up With GitHub",[261,7907,7908,7926],{"gap":263,"left-width":3013,"right-width":3012},[268,7909,7910],{"v-slot:left":270},[20,7911,7912,7917,7920,7923],{},[23,7913,360,7914],{},[70,7915,7916],{},"render.com",[23,7918,7919],{},"Choose GitHub sign-in",[23,7921,7922],{},"Authorize Render when prompted",[23,7924,7925],{},"Land on the Render dashboard",[268,7927,7928],{"v-slot:right":270},[108,7929,7930],{},[334,7931],{"alt":7932,"src":7933,"variant":338},"Render GitHub sign-in screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-01-github-signin.png",[11,7935,7937,7940],{"id":7936,"level":14},"step-2-new-web-service",[16,7938,7939],{"id":7936},"Step 2: New Web Service",[261,7941,7942,7962],{"gap":263,"left-width":3013,"right-width":3012},[268,7943,7944],{"v-slot:left":270},[20,7945,7946,7951,7956,7959],{},[23,7947,1004,7948],{},[70,7949,7950],{},"New +",[23,7952,3474,7953],{},[70,7954,7955],{},"Web Service",[23,7957,7958],{},"Do not choose a database service here",[23,7960,7961],{},"This creates the hosted PHP app",[268,7963,7964],{"v-slot:right":270},[108,7965,7966],{},[334,7967],{"alt":7968,"src":7969,"variant":338},"Render New menu with Web Service option","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-04-new-menu.png",[11,7971,7973,7977],{"id":7972,"level":14},"step-3-connect-repo",[16,7974,7976],{"id":7975},"step-3-connect-repository","Step 3: Connect Repository",[261,7978,7979,7999],{"gap":263,"left-width":264,"right-width":265},[268,7980,7981],{"v-slot:left":270},[20,7982,7983,7986,7989,7996],{},[23,7984,7985],{},"Select your student course repository",[23,7987,7988],{},"Authorize repository access if Render asks",[23,7990,7991,7992,7995],{},"Ensure it's the proper repository (format: ",[70,7993,7994],{},"ucid-course-section-semYear",")",[23,7997,7998],{},"Continue to service settings",[268,8000,8001],{"v-slot:right":270},[108,8002,8003],{},[334,8004],{"alt":8005,"src":8006,"variant":338},"Render repository selection screen","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-07-select-repo.png",[11,8008,8010,8014],{"id":8009,"level":14},"step-4-configure-qa",[16,8011,8013],{"id":8012},"step-4-configure-qa-service","Step 4: Configure QA Service",[261,8015,8016,8049],{"gap":263,"left-width":3013,"right-width":3012},[268,8017,8018,8021],{"v-slot:left":270},[108,8019,8020],{},"Use these settings:",[20,8022,8023,8027,8032,8038,8043,8046],{},[23,8024,7856,8025],{},[70,8026,7859],{},[23,8028,8029,8030],{},"Branch: ",[70,8031,6978],{},[23,8033,8034,8035],{},"Runtime: ",[70,8036,8037],{},"Docker",[23,8039,8040,8041],{},"Instance type: ",[70,8042,7789],{},[23,8044,8045],{},"Root directory: blank",[23,8047,8048],{},"Build\u002Fstart commands: blank",[268,8050,8051],{"v-slot:right":270},[108,8052,8053],{},[334,8054],{"alt":8055,"src":8056,"variant":338},"Render QA service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-08-qa-config-basic.png",[11,8058,8060,8064],{"id":8059,"level":14},"step-5-env-vars",[16,8061,8063],{"id":8062},"step-5-add-environment-variables","Step 5: Add Environment Variables",[261,8065,8066,8095],{"gap":263,"left-width":348,"right-width":349},[268,8067,8068],{"v-slot:left":270},[20,8069,8070,8083,8089,8092],{},[23,8071,8072,8073,8075],{},"Add ",[70,8074,6537],{},[20,8076,8077],{},[23,8078,8079,8080],{},"Get it from ",[86,8081,6542],{"href":313,"rel":8082},[90],[23,8084,8085,8086,8088],{},"Do not use \"add from ",[70,8087,6518],{},"\"",[23,8090,8091],{},"Add later API keys only when a later lesson requires them",[23,8093,8094],{},"Repeat required env vars on both QA and production",[268,8096,8097],{"v-slot:right":270},[108,8098,8099],{},[334,8100],{"alt":8101,"src":8102,"variant":338},"Render environment variables section","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-09-env-vars.png",[11,8104,8106,8109],{"id":8105,"level":14},"step-6-deploy-qa",[16,8107,8108],{"id":8105},"Step 6: Deploy QA",[261,8110,8111,8130],{"gap":263,"left-width":264,"right-width":265},[268,8112,8113],{"v-slot:left":270},[20,8114,8115,8118,8121,8124,8127],{},[23,8116,8117],{},"Create the QA service",[23,8119,8120],{},"Watch the first deploy log",[23,8122,8123],{},"Wait for a success state",[23,8125,8126],{},"Open the QA URL",[23,8128,8129],{},"Confirm the starter page loads",[268,8131,8132],{"v-slot:right":270},[108,8133,8134],{},[334,8135],{"alt":8136,"src":8137,"variant":338},"Successful Render QA deployment","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-10-qa-deployed.png",[11,8139,8141,8145],{"id":8140,"level":14},"step-7-create-prod",[16,8142,8144],{"id":8143},"step-7-create-production-service","Step 7: Create Production Service",[261,8146,8147,8176],{"gap":263,"left-width":3013,"right-width":3012},[268,8148,8149,8152],{"v-slot:left":270},[108,8150,8151],{},"Create a second web service:",[20,8153,8154,8157,8161,8165,8169,8173],{},[23,8155,8156],{},"Same repository",[23,8158,7856,8159],{},[70,8160,7886],{},[23,8162,8029,8163],{},[70,8164,6981],{},[23,8166,8034,8167],{},[70,8168,8037],{},[23,8170,8040,8171],{},[70,8172,7789],{},[23,8174,8175],{},"Same required env vars",[268,8177,8178],{"v-slot:right":270},[108,8179,8180],{},[334,8181],{"alt":8182,"src":8183,"variant":338},"Render production service configuration","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-11-prod-config.png",[11,8185,8186,8189],{"id":7404,"level":14},[16,8187,8188],{"id":7404},"Normal Workflow",[410,8190,8191,8194,8197,8202,8205,8208,8211,8218],{},[23,8192,8193],{},"Work locally on a feature or homework branch",[23,8195,8196],{},"Commit and push that branch to GitHub",[23,8198,8199,8200],{},"Open a pull request into ",[70,8201,6978],{},[23,8203,8204],{},"Merge after review",[23,8206,8207],{},"Render updates the QA URL",[23,8209,8210],{},"Test the QA URL",[23,8212,7471,8213,6731,8215,8217],{},[70,8214,6978],{},[70,8216,6981],{}," after evidence gathering",[23,8219,8220],{},"Render updates the production URL",[11,8222,8224,8227],{"id":8223,"level":14},"urls-and-cold-starts",[16,8225,8226],{"id":8223},"URLs And Cold Starts",[20,8228,8229,8232,8235,8238,8246],{},[23,8230,8231],{},"QA URL shows the test deployment",[23,8233,8234],{},"Production URL shows the stable deployment",[23,8236,8237],{},"Homework evidence usually starts with QA",[23,8239,8240,8241],{},"Free services may sleep after inactivity\n",[20,8242,8243],{},[23,8244,8245],{},"First visit after sleep may take extra time (2 - 5 minutes)",[23,8247,8248],{},"Do not submit before Render finishes deploying",[11,8250,8252,8255],{"id":8251,"level":14},"logs-and-status",[16,8253,8254],{"id":8251},"Logs And Status",[261,8256,8257,8273],{"gap":263,"left-width":264,"right-width":265},[268,8258,8259],{"v-slot:left":270},[20,8260,8261,8264,8267,8270],{},[23,8262,8263],{},"Logs show build and startup output",[23,8265,8266],{},"Dashboard status shows deploy progress",[23,8268,8269],{},"Failed deploys usually show the first useful clue",[23,8271,8272],{},"Read the first clear error before changing settings",[268,8274,8275],{"v-slot:right":270},[108,8276,8277],{},[334,8278],{"alt":8279,"src":8280,"variant":338},"Render deploy logs","\u002Fimages\u002Finternet-applications\u002Frender-setup\u002Frender-12-logs.png",[11,8282,8284,8287],{"id":8283,"level":14},"troubleshooting",[16,8285,8286],{"id":8283},"Troubleshooting",[20,8288,8289,8299,8307,8317],{},[23,8290,8291,8292],{},"Build fails\n",[20,8293,8294],{},[23,8295,7443,8296,8298],{},[70,8297,6186],{},", root directory, runtime, and instance type",[23,8300,8301,8302],{},"App deploys but page fails\n",[20,8303,8304],{},[23,8305,8306],{},"Check logs for PHP errors",[23,8308,8309,8310],{},"Database connection fails\n",[20,8311,8312],{},[23,8313,7443,8314,8316],{},[70,8315,6537],{}," spelling and copied value",[23,8318,8319,8320],{},"Wrong version appears\n",[20,8321,8322,8325],{},[23,8323,8324],{},"Confirm the service watches the expected branch",[23,8326,8327],{},"Clear browser cache or test in a private window",[11,8329,8330,8332],{"id":678,"level":14},[16,8331,681],{"id":678},[20,8333,8334,8344,8347,8352,8355,8358],{},[23,8335,8336,8337,8339,8340,159,8342],{},"Choosing ",[70,8338,2593],{}," instead of ",[70,8341,6978],{},[70,8343,6981],{},[23,8345,8346],{},"Creating one service for both environments",[23,8348,8349,8350],{},"Forgetting ",[70,8351,6537],{},[23,8353,8354],{},"Using a paid instance type by accident",[23,8356,8357],{},"Checking GitHub but not the Render URL",[23,8359,8360],{},"Changing code locally but forgetting to push and merge",[11,8362,8363,8365],{"id":724,"level":14},[16,8364,727],{"id":724},[261,8366,8367,8395],{"gap":263,"left-width":483,"right-width":483},[268,8368,8369,8371,8377,8383,8389],{"v-slot:left":270},[179,8370,735],{"id":734},[108,8372,8373,8376],{},[963,8374,8375],{},"Service"," - one deployed app on Render",[108,8378,8379,8382],{},[963,8380,8381],{},"Watched branch"," - Git branch Render deploys from",[108,8384,8385,8388],{},[963,8386,8387],{},"Environment variable"," - setting stored outside code",[108,8390,8391,8394],{},[963,8392,8393],{},"Deploy log"," - output from Render's build\u002Fstart process",[268,8396,8397,8399],{"v-slot:right":270},[179,8398,755],{"id":754},[20,8400,8401,8408,8415,8422],{},[23,8402,8403],{},[86,8404,8407],{"href":8405,"rel":8406},"https:\u002F\u002Frender.com\u002Fdocs\u002Fweb-services",[90],"Render Docs: Web Services",[23,8409,8410],{},[86,8411,8414],{"href":8412,"rel":8413},"https:\u002F\u002Frender.com\u002Fdocs\u002Fdeploys",[90],"Render Docs: Deploys",[23,8416,8417],{},[86,8418,8421],{"href":8419,"rel":8420},"https:\u002F\u002Frender.com\u002Fdocs\u002Fconfigure-environment-variables",[90],"Render Docs: Environment Variables",[23,8423,8424],{},[86,8425,8428],{"href":8426,"rel":8427},"https:\u002F\u002Frender.com\u002Fdocs\u002Ffree",[90],"Render Docs: Free Instance Types",[11,8430,8431,8433,8436],{"id":781,"level":14},[16,8432,784],{"id":781},[108,8434,8435],{},"Before leaving this presentation, confirm you:",[20,8437,8438,8441,8444,8451,8454,8457],{},[23,8439,8440],{},"Created QA and production Render services",[23,8442,8443],{},"Matched each service to the correct branch",[23,8445,8446,8447,6538,8449],{},"Added ",[70,8448,6537],{},[70,8450,6542],{},[23,8452,8453],{},"Opened each deployed URL",[23,8455,8456],{},"Read logs instead of assuming it worked",[23,8458,8459,8460],{},"Understand the local -> GitHub -> Render loop\n",[20,8461,8462,8465,8470],{},[23,8463,8464],{},"Majority of your work will be done locally and tested locally",[23,8466,8467,8469],{},[70,8468,6978],{}," is just for gathering evidence for submissions",[23,8471,8472,8474],{},[70,8473,6981],{}," is what will be verified during grading",{"title":270,"searchDepth":424,"depth":424,"links":8476},[8477,8478,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495],{"id":7696,"depth":424,"text":7688},{"id":3307,"depth":424,"text":3310},{"id":7743,"depth":424,"text":7746},{"id":1452,"depth":424,"text":1455},{"id":7840,"depth":424,"text":7843},{"id":7904,"depth":424,"text":7905},{"id":7936,"depth":424,"text":7939},{"id":7975,"depth":424,"text":7976},{"id":8012,"depth":424,"text":8013},{"id":8062,"depth":424,"text":8063},{"id":8105,"depth":424,"text":8108},{"id":8143,"depth":424,"text":8144},{"id":7404,"depth":424,"text":8188},{"id":8223,"depth":424,"text":8226},{"id":8251,"depth":424,"text":8254},{"id":8283,"depth":424,"text":8286},{"id":678,"depth":424,"text":681},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"Connect the course repository to Render, create QA and production services, and verify the deploy loop from GitHub to a live URL.","Face-to-face class of about 40 students; includes Render account setup, QA\u002Fprod service creation, environment variables, deploy verification, and first troubleshooting pass.",{},"80","\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",{"title":7688,"description":8496},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F08-render-setup",[8504,8505,6978,7680],"render","deployment","21:42","esZd5RIpqCQ","https:\u002F\u002Fyoutu.be\u002FesZd5RIpqCQ","Render.com Setup (QA and Prod)","_1jV7vdhppggQ8TAOecx_1jFvjG90__8eGGlaXbnc28",{"id":8512,"title":8513,"audience":6,"body":8514,"contentType":832,"course":158,"description":11188,"estimateBasis":11189,"estimatedDiscussionMinutes":11190,"estimatedLiveMinutes":11191,"estimatedTotalMinutes":11192,"extension":838,"meta":11193,"module":840,"navigation":841,"order":5317,"path":11194,"promptAssist":844,"seo":11195,"status":846,"stem":11196,"tags":11197,"videoDuration":11202,"videoId":11203,"videoLink":11204,"videoTitle":11205,"week":840,"__hash__":11206},"content\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox.md","Local Ubuntu Web Server With VirtualBox",{"type":8,"value":8515,"toc":11120},[8516,8545,8590,8626,8695,8727,8754,8786,8812,8841,8870,8897,8928,8956,8992,9057,9092,9138,9181,9225,9272,9335,9371,9406,9443,9476,9513,9546,9576,9606,9636,9666,9696,9730,9762,9794,9826,9875,9877,9920,9946,9987,10039,10118,10169,10200,10230,10260,10310,10335,10385,10433,10491,10549,10590,10620,10654,10688,10722,10773,10825,10844,10872,10920,10992,11092],[11,8517,8519,8522],{"id":8518,"level":14},"virtualbox-title",[16,8520,8513],{"id":8521},"local-ubuntu-web-server-with-virtualbox",[20,8523,8524,8527,8530,8533,8536,8542],{},[23,8525,8526],{},"Primary course path for the local Ubuntu VM",[23,8528,8529],{},"Create an Ubuntu Server VM in VirtualBox",[23,8531,8532],{},"Connect from your host terminal with SSH",[23,8534,8535],{},"Share the course repo into Ubuntu",[23,8537,8538,8539,8541],{},"Serve ",[70,8540,1637],{}," through Apache and PHP",[23,8543,8544],{},"Create a local MySQL database for testing",[11,8546,8548,8551,8554,8565,8568],{"id":8547,"level":14},"main-goal",[16,8549,8550],{"id":8547},"Main Goal",[108,8552,8553],{},"Your host computer and Ubuntu VM have different jobs:",[20,8555,8556,8559,8562],{},[23,8557,8558],{},"Host computer: edit files with VS Code and open the browser",[23,8560,8561],{},"Ubuntu VM: run Apache, PHP, MySQL, and server commands",[23,8563,8564],{},"Shared folder: lets both use the same course repo files",[108,8566,8567],{},"Target result:",[20,8569,8570,8576,8581,8584,8587],{},[23,8571,8572,8573],{},"Host browser opens ",[70,8574,8575],{},"http:\u002F\u002Flocalhost:3000",[23,8577,8578,8579],{},"Apache serves the repo's ",[70,8580,1637],{},[23,8582,8583],{},"PHP executes inside Ubuntu",[23,8585,8586],{},"Local MySQL has a database and user named after your UCID",[23,8588,8589],{},"Edits made on the host appear after browser refresh",[11,8591,8593,8596,8599,8618,8621],{"id":8592,"level":14},"virtualbox-caveat",[16,8594,8595],{"id":8592},"VirtualBox Caveat",[108,8597,8598],{},"VirtualBox is the primary local VM path for this course:",[20,8600,8601,8604,8607,8615],{},[23,8602,8603],{},"Works well on modern Windows, Linux, and Intel Mac hosts",[23,8605,8606],{},"Apple Silicon Mac requires an ARM64 Ubuntu Server ISO",[23,8608,8609,8610],{},"Windows on Arm support is experimental in VirtualBox\n",[20,8611,8612],{},[23,8613,8614],{},"Avoid unless your instructor confirms it for your machine",[23,8616,8617],{},"Arm hosts cannot run x86\u002FAMD64 guest images",[108,8619,8620],{},"VMware is the fallback path if VirtualBox is not a good fit for your machine",[2725,8622,8623],{"type":3994},[108,8624,8625],{},"Most students do not need BIOS changes. If VirtualBox cannot start the VM or does not offer a 64-bit Ubuntu option, check that Intel VT-x, AMD-V, or SVM is enabled in BIOS\u002FUEFI. On Windows, Hyper-V-related features can also interfere on some systems.",[11,8627,8628,8630],{"id":1452,"level":14},[16,8629,1455],{"id":1452},[20,8631,8632,8650,8668,8671,8674,8677,8692],{},[23,8633,8634,8635],{},"VirtualBox downloaded\n",[20,8636,8637,8644,8647],{},[23,8638,8639],{},[86,8640,8643],{"href":8641,"rel":8642},"https:\u002F\u002Fwww.virtualbox.org\u002Fwiki\u002FDownloads",[90],"VirtualBox downloads",[23,8645,8646],{},"Windows\u002FLinux\u002FIntel Mac: use the standard host installer",[23,8648,8649],{},"Apple Silicon Mac: use the macOS Arm64 host installer",[23,8651,8652,8653],{},"Ubuntu Server ISO downloaded\n",[20,8654,8655,8662,8665],{},[23,8656,8657],{},[86,8658,8661],{"href":8659,"rel":8660},"https:\u002F\u002Fubuntu.com\u002Fdownload\u002Fserver#how-to-install-tab-lts",[90],"Ubuntu Server installer",[23,8663,8664],{},"Apple Silicon Mac: use the ARM64 server ISO",[23,8666,8667],{},"Windows, Linux, and Intel Mac: use the AMD64 server ISO",[23,8669,8670],{},"Internet Applications course repo cloned on host computer",[23,8672,8673],{},"Git\u002FGitHub setup already working",[23,8675,8676],{},"Administrator access on your computer",[23,8678,8679,8680,8683,8684],{},"At least ",[70,8681,8682],{},"10 GB"," free disk space for the VM\n",[20,8685,8686],{},[23,8687,8688,8691],{},[70,8689,8690],{},"20-25 GB"," is safer if your computer has room",[23,8693,8694],{},"Stable internet for package installs",[11,8696,8698,8701],{"id":8697,"level":14},"setup-parts",[16,8699,8700],{"id":8697},"Setup Parts",[20,8702,8703,8706,8709,8712,8718,8721,8724],{},[23,8704,8705],{},"VM: Ubuntu Server running inside VirtualBox",[23,8707,8708],{},"NAT adapter: gives the VM internet access",[23,8710,8711],{},"Port forwarding: lets the host reach SSH and Apache",[23,8713,8714,8715],{},"SSH: lets the host terminal control Ubuntu through ",[70,8716,8717],{},"localhost",[23,8719,8720],{},"Shared folder: exposes the host repo inside Ubuntu",[23,8722,8723],{},"Apache\u002FPHP: serves and executes the web app",[23,8725,8726],{},"MySQL: local database server for local testing",[11,8728,8730,8734],{"id":8729,"level":14},"install-virtualbox-windows",[16,8731,8733],{"id":8732},"install-virtualbox-on-windows","Install VirtualBox On Windows",[20,8735,8736,8739,8742,8745,8748,8751],{},[23,8737,8738],{},"Download VirtualBox for Windows hosts",[23,8740,8741],{},"Run the installer as an administrator if prompted",[23,8743,8744],{},"Keep the default install path and features",[23,8746,8747],{},"Accept the network reset warning",[23,8749,8750],{},"Open VirtualBox after installation",[23,8752,8753],{},"See the slides below for the Windows installer screens",[11,8755,8757,8760],{"id":8756,"level":255},"windows-installer-start",[16,8758,8759],{"id":8756},"Windows Installer: Start",[261,8761,8762,8770],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8763,8764],{"v-slot:left":270},[108,8765,8766],{},[334,8767],{"alt":8768,"src":8769,"variant":338},"VirtualBox Windows installer start screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step1.png",[268,8771,8772],{"v-slot:right":270},[20,8773,8774,8780,8783],{},[23,8775,8776,8777],{},"Launch the downloaded ",[70,8778,8779],{},".exe",[23,8781,8782],{},"Approve the Windows security prompt if shown",[23,8784,8785],{},"Start the setup wizard",[11,8787,8789,8792],{"id":8788,"level":255},"windows-installer-features",[16,8790,8791],{"id":8788},"Windows Installer: Features",[261,8793,8794,8802],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8795,8796],{"v-slot:left":270},[108,8797,8798],{},[334,8799],{"alt":8800,"src":8801,"variant":338},"VirtualBox Windows installer feature selection screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step2.png",[268,8803,8804],{"v-slot:right":270},[20,8805,8806,8809],{},[23,8807,8808],{},"Keep the default install location",[23,8810,8811],{},"Keep the default features selected",[11,8813,8815,8818],{"id":8814,"level":255},"windows-installer-network-warning",[16,8816,8817],{"id":8814},"Windows Installer: Network Warning",[261,8819,8820,8828],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8821,8822],{"v-slot:left":270},[108,8823,8824],{},[334,8825],{"alt":8826,"src":8827,"variant":338},"VirtualBox Windows installer network warning","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step3.png",[268,8829,8830],{"v-slot:right":270},[20,8831,8832,8835,8838],{},[23,8833,8834],{},"VirtualBox may reset network adapters briefly",[23,8836,8837],{},"This is expected during install",[23,8839,8840],{},"Save web work before continuing if needed",[11,8842,8844,8847],{"id":8843,"level":255},"windows-installer-ready",[16,8845,8846],{"id":8843},"Windows Installer: Ready",[261,8848,8849,8857],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8850,8851],{"v-slot:left":270},[108,8852,8853],{},[334,8854],{"alt":8855,"src":8856,"variant":338},"VirtualBox Windows installer ready screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step4.png",[268,8858,8859],{"v-slot:right":270},[20,8860,8861,8864,8867],{},[23,8862,8863],{},"Start the installation",[23,8865,8866],{},"Keep the default choices",[23,8868,8869],{},"Wait for the installer to request permissions if needed",[11,8871,8873,8877],{"id":8872,"level":255},"windows-installer-progress",[16,8874,8876],{"id":8875},"windows-installer-start-options","Windows Installer: Start Options",[261,8878,8879,8887],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8880,8881],{"v-slot:left":270},[108,8882,8883],{},[334,8884],{"alt":8885,"src":8886,"variant":338},"VirtualBox Windows installer progress screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step5.png",[268,8888,8889],{"v-slot:right":270},[20,8890,8891,8894],{},[23,8892,8893],{},"No need to create a Start Menu item or desktop shortcut unless desired",[23,8895,8896],{},"Third option is likely optional too since we'll be using the VirtualBox Manager",[11,8898,8900,8903],{"id":8899,"level":255},"windows-installer-permission",[16,8901,8902],{"id":8899},"Windows Installer: Permission",[261,8904,8905,8913],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8906,8907],{"v-slot:left":270},[108,8908,8909],{},[334,8910],{"alt":8911,"src":8912,"variant":338},"VirtualBox Windows installer permission prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step6.png",[268,8914,8915],{"v-slot:right":270},[20,8916,8917,8920],{},[23,8918,8919],{},"Proceed with install",[23,8921,8922,8923],{},"Approve VirtualBox driver prompts\n",[20,8924,8925],{},[23,8926,8927],{},"These let VirtualBox create virtual hardware",[11,8929,8931,8934],{"id":8930,"level":255},"windows-installer-complete",[16,8932,8933],{"id":8930},"Windows Installer: Complete",[261,8935,8936,8944],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,8937,8938],{"v-slot:left":270},[108,8939,8940],{},[334,8941],{"alt":8942,"src":8943,"variant":338},"VirtualBox Windows installer completion screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_step7.png",[268,8945,8946],{"v-slot:right":270},[20,8947,8948,8950,8953],{},[23,8949,2873],{},[23,8951,8952],{},"Open VirtualBox",[23,8954,8955],{},"Continue to VM creation",[11,8957,8959,8963],{"id":8958,"level":14},"install-virtualbox-macos",[16,8960,8962],{"id":8961},"install-virtualbox-on-macos","Install VirtualBox On macOS",[261,8964,8965,8984],{"gap":263,"left-width":348,"right-width":349,"stack":2509},[268,8966,8967],{"v-slot:left":270},[20,8968,8969,8972,8975,8978,8981],{},[23,8970,8971],{},"Install the VirtualBox host package for your Mac CPU type",[23,8973,8974],{},"Intel Mac: standard macOS host installer",[23,8976,8977],{},"Apple Silicon Mac: Arm64 host installer and Arm64 Ubuntu Server ISO",[23,8979,8980],{},"Approve macOS security prompts if needed",[23,8982,8983],{},"If VirtualBox is not a good fit, use the VMware fallback lesson",[268,8985,8986],{"v-slot:right":270},[108,8987,8988],{},[334,8989],{"alt":8990,"src":8991,"variant":338},"Summary of macOS VirtualBox setup notes","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvm_summary_mac.png",[11,8993,8995,8999,9002],{"id":8994,"level":14},"step-1-create-vm",[16,8996,8998],{"id":8997},"step-1-create-the-vm","Step 1: Create The VM",[108,9000,9001],{},"Create a lightweight Ubuntu Server VM:",[20,9003,9004,9007,9015,9030,9042,9048,9051,9054],{},[23,9005,9006],{},"Type: Linux",[23,9008,9009,9010],{},"Version: Ubuntu 64-bit or Ubuntu Arm64\n",[20,9011,9012],{},[23,9013,9014],{},"Match the version to the ISO you downloaded",[23,9016,9017,9018,9021,9022],{},"Memory: ",[70,9019,9020],{},"1 GB"," course target\n",[20,9023,9024],{},[23,9025,1960,9026,9029],{},[70,9027,9028],{},"1.5-2 GB"," if the installer is too slow or refuses to continue (you shouldn't need to do this)",[23,9031,9032,9033,9035,9036],{},"Disk: ",[70,9034,8682],{}," course minimum\n",[20,9037,9038],{},[23,9039,9040,8691],{},[70,9041,8690],{},[23,9043,9044,9045,9047],{},"CPU: ",[70,9046,840],{}," core is enough for this course VM",[23,9049,9050],{},"Enable OpenSSH during install if prompted",[23,9052,9053],{},"Username: use your UCID",[23,9055,9056],{},"See the slides below for VM settings and Ubuntu install screens",[11,9058,9060,9063],{"id":9059,"level":255},"vm-setup-name-and-iso",[16,9061,9062],{"id":9059},"VM Setup: Name And ISO",[261,9064,9065,9073],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,9066,9067],{"v-slot:left":270},[108,9068,9069],{},[334,9070],{"alt":9071,"src":9072,"variant":338},"VirtualBox VM name and ISO setup","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_1.png",[268,9074,9075],{"v-slot:right":270},[20,9076,9077,9080,9086,9089],{},[23,9078,9079],{},"Start a new virtual machine",[23,9081,9082,9083],{},"Name it clearly, such as ",[70,9084,9085],{},"it202-vm",[23,9087,9088],{},"Choose the Ubuntu Server ISO file next",[23,9090,9091],{},"OS fields may look wrong until the ISO is selected",[11,9093,9095,9098],{"id":9094,"level":255},"vm-setup-confirm-ubuntu-iso",[16,9096,9097],{"id":9094},"VM Setup: Confirm Ubuntu ISO",[261,9099,9100,9108],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,9101,9102],{"v-slot:left":270},[108,9103,9104],{},[334,9105],{"alt":9106,"src":9107,"variant":338},"VirtualBox VM name and Ubuntu ISO selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_2.png",[268,9109,9110],{"v-slot:right":270},[20,9111,9112,9118,9124,9127],{},[23,9113,9114,9115],{},"Confirm OS is ",[70,9116,9117],{},"Linux",[23,9119,9120,9121],{},"Confirm distribution is ",[70,9122,9123],{},"Ubuntu",[23,9125,9126],{},"Confirm version matches your ISO",[23,9128,2527,9129,9132,9133],{},[70,9130,9131],{},"Unattended Installation"," off\n",[20,9134,9135],{},[23,9136,9137],{},"The Ubuntu installer screens are easier to teach manually",[11,9139,9141,9144],{"id":9140,"level":255},"vm-setup-memory-and-cpu",[16,9142,9143],{"id":9140},"VM Setup: Memory And CPU",[261,9145,9146,9154],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,9147,9148],{"v-slot:left":270},[108,9149,9150],{},[334,9151],{"alt":9152,"src":9153,"variant":338},"VirtualBox VM memory and CPU settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_4.png",[268,9155,9156],{"v-slot:right":270},[20,9157,9158,9171,9175,9178],{},[23,9159,9017,9160,9021,9163],{},[70,9161,9162],{},"1024 MB",[20,9164,9165,9168],{},[23,9166,9167],{},"The goal is to match free-tier cloud services",[23,9169,9170],{},"Demonstrates that small apps can run with limited resources",[23,9172,9044,9173],{},[70,9174,840],{},[23,9176,9177],{},"Keep EFI off unless your machine requires it",[23,9179,9180],{},"This VM is for Apache, PHP, MySQL, and local development\u002Ftesting",[11,9182,9184,9187],{"id":9183,"level":255},"vm-setup-virtual-disk",[16,9185,9186],{"id":9183},"VM Setup: Virtual Disk",[261,9188,9189,9197],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,9190,9191],{"v-slot:left":270},[108,9192,9193],{},[334,9194],{"alt":9195,"src":9196,"variant":338},"VirtualBox virtual hard disk settings","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_5.png",[268,9198,9199],{"v-slot:right":270},[20,9200,9201,9207,9210,9222],{},[23,9202,9203,9204],{},"Disk type: ",[70,9205,9206],{},"VDI",[23,9208,9209],{},"Storage: dynamically allocated",[23,9211,9212,9213,9215],{},"Minimum: ",[70,9214,8682],{},[20,9216,9217],{},[23,9218,9219,9221],{},[70,9220,8690],{}," is safer if you have room",[23,9223,9224],{},"Dynamic disk uses space as needed, not all at once",[11,9226,9228,9231],{"id":9227,"level":255},"vm-setup-start-with-gui",[16,9229,9230],{"id":9227},"VM Setup: Start With GUI",[261,9232,9233,9241],{"gap":263,"left-width":2508,"right-width":264,"stack":2509},[268,9234,9235],{"v-slot:left":270},[108,9236,9237],{},[334,9238],{"alt":9239,"src":9240,"variant":338},"VirtualBox VM selected with the Start button visible","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_setup_6.png",[268,9242,9243],{"v-slot:right":270},[20,9244,9245,9248,9258,9261],{},[23,9246,9247],{},"Select the newly created VM",[23,9249,1004,9250,9253],{},[70,9251,9252],{},"Start",[20,9254,9255],{},[23,9256,9257],{},"Choose the normal GUI start for the first boot",[23,9259,9260],{},"Complete the Ubuntu installer in the VM window",[23,9262,9263,9264],{},"After install and SSH setup, future starts can be headless\n",[20,9265,9266],{},[23,9267,9268,9269,9271],{},"You will connect with ",[70,9270,4386],{}," when you need the VM",[11,9273,9275,9279,9282],{"id":9274,"level":14},"ubuntu-installer",[16,9276,9278],{"id":9277},"step-2-ubuntu-installer","Step 2: Ubuntu Installer",[108,9280,9281],{},"Use the Ubuntu Server installer after the VM starts:",[20,9283,9284,9287,9290,9293,9296,9299,9332],{},[23,9285,9286],{},"Choose the default course options unless noted",[23,9288,9289],{},"Continue without updating the installer if instructed",[23,9291,9292],{},"Use your UCID for the Ubuntu username",[23,9294,9295],{},"Install OpenSSH server during setup",[23,9297,9298],{},"Skip optional server snaps",[23,9300,9301,9302],{},"Keyboard navigation:\n",[20,9303,9304,9311,9321,9327],{},[23,9305,9306,9310],{},[9307,9308,9309],"kbd",{},"Tab"," moves between fields and buttons",[23,9312,9313,9316,9317,9320],{},[9307,9314,9315],{},"Up"," \u002F ",[9307,9318,9319],{},"Down"," moves through lists",[23,9322,9323,9326],{},[9307,9324,9325],{},"Space"," toggles checkboxes",[23,9328,9329,9331],{},[9307,9330,2043],{}," confirms the selected option",[23,9333,9334],{},"See the slides below for the installer screens",[11,9336,9338,9342],{"id":9337,"level":255},"ubuntu-installer-boot-menu",[16,9339,9341],{"id":9340},"step-21-boot-menu","Step 2.1: Boot Menu",[261,9343,9346,9355],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},"1.75fr","0.65fr",[268,9347,9348],{"v-slot:left":270},[108,9349,9350],{},[334,9351],{"alt":9352,"src":9353,"variant":9354},"Ubuntu Server boot menu in VirtualBox","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_1.png","slide-screenshot",[268,9356,9357],{"v-slot:right":270},[20,9358,9359,9364,9368],{},[23,9360,3474,9361],{},[70,9362,9363],{},"Try or Install Ubuntu Server",[23,9365,2075,9366],{},[9307,9367,2043],{},[23,9369,9370],{},"This starts the Ubuntu Server installer",[11,9372,9374,9378],{"id":9373,"level":255},"ubuntu-installer-language",[16,9375,9377],{"id":9376},"step-22-language","Step 2.2: Language",[261,9379,9380,9388],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9381,9382],{"v-slot:left":270},[108,9383,9384],{},[334,9385],{"alt":9386,"src":9387,"variant":9354},"Ubuntu Server installer language screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.0.png",[268,9389,9390],{"v-slot:right":270},[20,9391,9392,9395,9401],{},[23,9393,9394],{},"Choose your preferred language",[23,9396,9397,9400],{},[70,9398,9399],{},"English"," is the expected course screenshot path",[23,9402,2075,9403,9405],{},[9307,9404,2043],{}," to continue",[11,9407,9409,9413],{"id":9408,"level":255},"ubuntu-installer-update",[16,9410,9412],{"id":9411},"step-23-update-prompt","Step 2.3: Update Prompt",[261,9414,9415,9423],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9416,9417],{"v-slot:left":270},[108,9418,9419],{},[334,9420],{"alt":9421,"src":9422,"variant":9354},"Ubuntu Server installer update prompt","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_2.5.png",[268,9424,9425],{"v-slot:right":270},[20,9426,9427,9437,9440],{},[23,9428,3474,9429,9432],{},[70,9430,9431],{},"Continue without updating",[20,9433,9434],{},[23,9435,9436],{},"If I forget to update the image, it's the second option",[23,9438,9439],{},"Keeps the install path consistent",[23,9441,9442],{},"Package updates happen after Ubuntu is installed",[11,9444,9446,9450],{"id":9445,"level":255},"ubuntu-installer-keyboard",[16,9447,9449],{"id":9448},"step-24-keyboard","Step 2.4: Keyboard",[261,9451,9452,9460],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9453,9454],{"v-slot:left":270},[108,9455,9456],{},[334,9457],{"alt":9458,"src":9459,"variant":9354},"Ubuntu Server installer keyboard screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_3.png",[268,9461,9462],{"v-slot:right":270},[20,9463,9464,9467,9473],{},[23,9465,9466],{},"Keep the detected keyboard layout if it matches",[23,9468,9469,9470],{},"Common setting: ",[70,9471,9472],{},"English (US)",[23,9474,9475],{},"Use Identify keyboard only if typing is wrong",[11,9477,9479,9483],{"id":9478,"level":255},"ubuntu-installer-install-type",[16,9480,9482],{"id":9481},"step-25-install-type","Step 2.5: Install Type",[261,9484,9485,9493],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9486,9487],{"v-slot:left":270},[108,9488,9489],{},[334,9490],{"alt":9491,"src":9492,"variant":9354},"Ubuntu Server installer installation type screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_4.png",[268,9494,9495],{"v-slot:right":270},[20,9496,9497,9507,9510],{},[23,9498,9499,9500,9503,9504],{},"Select ",[70,9501,9502],{},"Ubuntu Server (minimized)","; don't choose full ",[70,9505,9506],{},"Ubuntu Server",[23,9508,9509],{},"Keep third-party drivers unchecked",[23,9511,9512],{},"Minimized keeps the VM lighter and aids future lessons",[11,9514,9516,9520],{"id":9515,"level":255},"ubuntu-installer-network",[16,9517,9519],{"id":9518},"step-26-network","Step 2.6: Network",[261,9521,9522,9530],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9523,9524],{"v-slot:left":270},[108,9525,9526],{},[334,9527],{"alt":9528,"src":9529,"variant":9354},"Ubuntu Server installer network configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_5.png",[268,9531,9532],{"v-slot:right":270},[20,9533,9534,9537,9543],{},[23,9535,9536],{},"DHCP address is expected",[23,9538,9539,9542],{},[70,9540,9541],{},"10.0.2.15"," is normal for VirtualBox NAT",[23,9544,9545],{},"Leave the network settings alone",[11,9547,9549,9553],{"id":9548,"level":255},"ubuntu-installer-proxy",[16,9550,9552],{"id":9551},"step-27-proxy","Step 2.7: Proxy",[261,9554,9555,9563],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9556,9557],{"v-slot:left":270},[108,9558,9559],{},[334,9560],{"alt":9561,"src":9562,"variant":9354},"Ubuntu Server installer proxy screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_6.png",[268,9564,9565],{"v-slot:right":270},[20,9566,9567,9570,9573],{},[23,9568,9569],{},"Leave proxy blank",[23,9571,9572],{},"Only fill this in if your network requires a proxy",[23,9574,9575],{},"Most student home networks do not need one",[11,9577,9579,9583],{"id":9578,"level":255},"ubuntu-installer-mirror",[16,9580,9582],{"id":9581},"step-28-mirror","Step 2.8: Mirror",[261,9584,9585,9593],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9586,9587],{"v-slot:left":270},[108,9588,9589],{},[334,9590],{"alt":9591,"src":9592,"variant":9354},"Ubuntu Server installer archive mirror screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_7.png",[268,9594,9595],{"v-slot:right":270},[20,9596,9597,9600,9603],{},[23,9598,9599],{},"Keep the default Ubuntu archive mirror",[23,9601,9602],{},"Wait for the mirror check to finish",[23,9604,9605],{},"Continue when the installer allows it",[11,9607,9609,9613],{"id":9608,"level":255},"ubuntu-installer-storage-guided",[16,9610,9612],{"id":9611},"step-29-guided-storage","Step 2.9: Guided Storage",[261,9614,9615,9623],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9616,9617],{"v-slot:left":270},[108,9618,9619],{},[334,9620],{"alt":9621,"src":9622,"variant":9354},"Ubuntu Server installer guided storage screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_8.png",[268,9624,9625],{"v-slot:right":270},[20,9626,9627,9630,9633],{},[23,9628,9629],{},"Use the entire virtual disk",[23,9631,9632],{},"LVM is optional, not needed for this course VM",[23,9634,9635],{},"Leave encryption off",[11,9637,9639,9643],{"id":9638,"level":255},"ubuntu-installer-storage-summary",[16,9640,9642],{"id":9641},"step-210-storage-summary","Step 2.10: Storage Summary",[261,9644,9645,9653],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9646,9647],{"v-slot:left":270},[108,9648,9649],{},[334,9650],{"alt":9651,"src":9652,"variant":9354},"Ubuntu Server installer storage summary screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_9.png",[268,9654,9655],{"v-slot:right":270},[20,9656,9657,9660,9663],{},[23,9658,9659],{},"Confirm the virtual disk is selected",[23,9661,9662],{},"This only affects the VM disk file",[23,9664,9665],{},"Continue when the layout looks correct",[11,9667,9669,9673],{"id":9668,"level":255},"ubuntu-installer-confirm-storage",[16,9670,9672],{"id":9671},"step-211-confirm-storage","Step 2.11: Confirm Storage",[261,9674,9675,9683],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9676,9677],{"v-slot:left":270},[108,9678,9679],{},[334,9680],{"alt":9681,"src":9682,"variant":9354},"Ubuntu Server installer destructive action confirmation","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_10.png",[268,9684,9685],{"v-slot:right":270},[20,9686,9687,9690,9693],{},[23,9688,9689],{},"Confirm the virtual disk format",[23,9691,9692],{},"This does not erase your host computer files",[23,9694,9695],{},"It formats the VM's virtual disk",[11,9697,9699,9703],{"id":9698,"level":255},"ubuntu-installer-profile",[16,9700,9702],{"id":9701},"step-212-profile","Step 2.12: Profile",[261,9704,9705,9713],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9706,9707],{"v-slot:left":270},[108,9708,9709],{},[334,9710],{"alt":9711,"src":9712,"variant":9354},"Ubuntu Server installer profile configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_11.png",[268,9714,9715],{"v-slot:right":270},[20,9716,9717,9720,9725,9727],{},[23,9718,9719],{},"Your name: your UCID or name is fine",[23,9721,9722,9723],{},"Server name: ",[70,9724,9085],{},[23,9726,299],{},[23,9728,9729],{},"Choose a password you can type reliably (it can be simple since it's only for local work)",[11,9731,9733,9737],{"id":9732,"level":255},"ubuntu-installer-pro",[16,9734,9736],{"id":9735},"step-213-ubuntu-pro","Step 2.13: Ubuntu Pro",[261,9738,9739,9747],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9740,9741],{"v-slot:left":270},[108,9742,9743],{},[334,9744],{"alt":9745,"src":9746,"variant":9354},"Ubuntu Server installer Ubuntu Pro screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_12.png",[268,9748,9749],{"v-slot:right":270},[20,9750,9751,9756,9759],{},[23,9752,3474,9753],{},[70,9754,9755],{},"Skip for now",[23,9757,9758],{},"Ubuntu Pro is not needed for the course VM",[23,9760,9761],{},"You can continue without an Ubuntu account",[11,9763,9765,9769],{"id":9764,"level":255},"ubuntu-installer-ssh",[16,9766,9768],{"id":9767},"step-214-ssh","Step 2.14: SSH",[261,9770,9771,9779],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9772,9773],{"v-slot:left":270},[108,9774,9775],{},[334,9776],{"alt":9777,"src":9778,"variant":9354},"Ubuntu Server installer SSH configuration screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_13.png",[268,9780,9781],{"v-slot:right":270},[20,9782,9783,9788,9791],{},[23,9784,7443,9785],{},[70,9786,9787],{},"Install OpenSSH server",[23,9789,9790],{},"Password authentication is fine for this local VM",[23,9792,9793],{},"No need to import SSH keys for this course setup",[11,9795,9797,9801],{"id":9796,"level":255},"ubuntu-installer-snaps",[16,9798,9800],{"id":9799},"step-215-featured-snaps","Step 2.15: Featured Snaps",[261,9802,9803,9811],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9804,9805],{"v-slot:left":270},[108,9806,9807],{},[334,9808],{"alt":9809,"src":9810,"variant":9354},"Ubuntu Server installer featured server snaps screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_14.png",[268,9812,9813],{"v-slot:right":270},[20,9814,9815,9818,9823],{},[23,9816,9817],{},"Leave all featured snaps unchecked",[23,9819,9820,9821],{},"Apache, PHP, and MySQL are installed later with ",[70,9822,6653],{},[23,9824,9825],{},"Continue without selecting extra packages",[11,9827,9829,9833],{"id":9828,"level":255},"ubuntu-installer-installing",[16,9830,9832],{"id":9831},"step-216-installing","Step 2.16: Installing",[261,9834,9835,9843],{"gap":838,"left-width":9344,"right-width":9345,"stack":2509},[268,9836,9837],{"v-slot:left":270},[108,9838,9839],{},[334,9840],{"alt":9841,"src":9842,"variant":9354},"Ubuntu Server installer installing system screen","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_vm_15.png",[268,9844,9845,9870],{"v-slot:right":270},[20,9846,9847,9850,9853,9861,9867],{},[23,9848,9849],{},"Installation can take a while",[23,9851,9852],{},"High CPU during install is normal",[23,9854,9855,9856,9858,9859],{},"If install struggles at ",[70,9857,9020],{},", recreate the VM with ",[70,9860,9028],{},[23,9862,9863,9864,9866],{},"Keep the course target at ",[70,9865,9020],{}," after setup if possible",[23,9868,9869],{},"Reboot once complete",[2725,9871,9872],{"type":3994},[108,9873,9874],{},"These target resources stay close to common cloud free-tier VMs",[108,9876,2733],{},[11,9878,9880,9884,9887],{"id":9879,"level":14},"step-2-networking",[16,9881,9883],{"id":9882},"virtualbox-configure-networking","VirtualBox: Configure Networking",[108,9885,9886],{},"Use one NAT adapter with port forwarding:",[20,9888,9889,9895,9904,9912,9917],{},[23,9890,9891,9892],{},"VM internet: ",[70,9893,9894],{},"NAT",[23,9896,9897,9898,9901,9902],{},"Host SSH: host ",[70,9899,9900],{},"22"," -> guest ",[70,9903,9900],{},[23,9905,9906,9907,9901,9910],{},"Host browser: host ",[70,9908,9909],{},"3000",[70,9911,8499],{},[23,9913,1960,9914,9916],{},[70,9915,8717],{}," from the host computer",[23,9918,9919],{},"See the slides below for adapter and port-forwarding screens",[11,9921,9923,9927,9940],{"id":9922,"level":255},"adapter-settings-screen",[16,9924,9926],{"id":9925},"adapter-settings","Adapter Settings",[20,9928,9929,9932,9937],{},[23,9930,9931],{},"Adapter 1 enabled",[23,9933,9934,9935],{},"Attached to ",[70,9936,9894],{},[23,9938,9939],{},"No second adapter needed for the baseline path",[108,9941,9942],{},[334,9943],{"alt":9944,"src":9945,"variant":9354},"VirtualBox Adapter 1 configured as NAT","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1.png",[11,9947,9949,9953,9981],{"id":9948,"level":255},"port-forwarding-screen",[16,9950,9952],{"id":9951},"port-forwarding","Port Forwarding",[20,9954,9955,9963,9970],{},[23,9956,9957,9958,9960,9961],{},"SSH: host ",[70,9959,9900],{}," to guest ",[70,9962,9900],{},[23,9964,9965,9966,9960,9968],{},"Apache HTTP: host ",[70,9967,9909],{},[70,9969,8499],{},[23,9971,9972,9973,9975,9976,9960,9979],{},"If host ",[70,9974,9900],{}," is already busy, use host ",[70,9977,9978],{},"2222",[70,9980,9900],{},[108,9982,9983],{},[334,9984],{"alt":9985,"src":9986,"variant":9354},"VirtualBox NAT port forwarding rules","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_adapter_1_ports.png",[11,9988,9990,9994,9997,10000,10003,10006],{"id":9989,"level":14},"step-3-connect-ssh",[16,9991,9993],{"id":9992},"step-3-connect-with-ssh","Step 3: Connect With SSH",[108,9995,9996],{},"Run from your host terminal:",[540,9998],{"language":542,"src":9999},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-01.sh",[108,10001,10002],{},"First connection prompt:",[540,10004],{"language":663,"src":10005},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-3-connect-with-ssh-02.txt",[20,10007,10008,10015,10024,10027,10030],{},[23,10009,10010,10011,10014],{},"Replace ",[70,10012,10013],{},"your_ucid"," with your UCID",[23,10016,10017,10018,10020,10021,10023],{},"Type ",[70,10019,3921],{}," once for this course VM on ",[70,10022,8717],{}," (if prompted like the example above)",[23,10025,10026],{},"Enter your Ubuntu password",[23,10028,10029],{},"After login, commands run inside Ubuntu",[23,10031,10032,159,10035,10038],{},[70,10033,10034],{},"exit",[70,10036,10037],{},"logout"," disconnects from the VM",[11,10040,10042,10046,10049],{"id":10041,"level":14},"step-4-confirm-network",[16,10043,10045],{"id":10044},"step-4-confirm-vm-network","Step 4: Confirm VM Network",[108,10047,10048],{},"Run inside Ubuntu through SSH:",[261,10050,10051,10093],{"gap":263,"left-width":265,"right-width":483,"stack":2509},[268,10052,10053,10056,10059],{"v-slot:left":270},[108,10054,10055],{},"Network check:",[540,10057],{"language":542,"src":10058},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-4-confirm-vm-networ-03.sh",[20,10060,10061,10067,10073,10079,10085],{},[23,10062,10063,10066],{},[70,10064,10065],{},"ping",": confirms basic network access",[23,10068,10069,10072],{},[70,10070,10071],{},"-c 4",": stop after four replies",[23,10074,10075,10078],{},[70,10076,10077],{},"apt update",": refreshes package indexes",[23,10080,10081,10084],{},[70,10082,10083],{},"apt upgrade",": applies available package updates",[23,10086,2970,10087,10089,10090],{},[70,10088,10065],{}," is not found, run ",[70,10091,10092],{},"sudo apt install iputils-ping",[268,10094,10095,10098,10101],{"v-slot:right":270},[108,10096,10097],{},"Port-forwarding check:",[540,10099],{"language":542,"src":10100},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fslide-id-summary-level-2-04.sh",[20,10102,10103,10108,10111,10115],{},[23,10104,10105,10106],{},"The VM may show ",[70,10107,9541],{},[23,10109,10110],{},"That is normal for VirtualBox NAT",[23,10112,1960,10113,9916],{},[70,10114,8717],{},[23,10116,10117],{},"Port forwarding routes host traffic into the VM",[11,10119,10121,10125],{"id":10120,"level":14},"step-5-shared-folder",[16,10122,10124],{"id":10123},"step-5-enable-shared-folder","Step 5: Enable Shared Folder",[261,10126,10127,10161],{"gap":263,"left-width":264,"right-width":265,"stack":2509},[268,10128,10129,10132],{"v-slot:left":270},[108,10130,10131],{},"In VirtualBox:",[20,10133,10134,10137,10140,10143,10146,10149,10152,10155,10158],{},[23,10135,10136],{},"Open VM settings",[23,10138,10139],{},"Choose Shared Folders",[23,10141,10142],{},"Folder Path: your cloned course repository folder",[23,10144,10145],{},"Folder Name: a simple repo name with no spaces",[23,10147,10148],{},"Mount Point: leave blank",[23,10150,10151],{},"Read-only: off",[23,10153,10154],{},"Auto-mount: on",[23,10156,10157],{},"Make Machine-permanent: on",[23,10159,10160],{},"Make Global: off",[268,10162,10163],{"v-slot:right":270},[108,10164,10165],{},[334,10166],{"alt":10167,"src":10168,"variant":338},"VirtualBox shared folder settings with the course repo selected","\u002Fimages\u002Finternet-applications\u002Fvirtualbox\u002Fvb_shared_folder.png",[11,10170,10172,10176,10179,10182],{"id":10171,"level":14},"step-6-guest-additions",[16,10173,10175],{"id":10174},"step-6-install-shared-folder-support","Step 6: Install Shared Folder Support",[108,10177,10178],{},"Run inside Ubuntu:",[540,10180],{"language":542,"src":10181},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-install-shared-fo-05.sh",[20,10183,10184,10191,10197],{},[23,10185,397,10186,322,10188,10190],{},[70,10187,10077],{},[70,10189,10083],{}," first only if you skipped the Step 4 updates",[23,10192,10193,10196],{},[70,10194,10195],{},"virtualbox-guest-utils",": VirtualBox shared-folder support",[23,10198,10199],{},"Reboot after the group step on the next slide",[11,10201,10203,10207,10210,10213],{"id":10202,"level":255},"step-6b-confirm-vboxsf",[16,10204,10206],{"id":10205},"step-61-check-the-shared-folder","Step 6.1: Check The Shared Folder",[108,10208,10209],{},"Reconnect with SSH, then run inside Ubuntu:",[540,10211],{"language":542,"src":10212},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-6-1-check-the-share-06.sh",[20,10214,10215,10221,10227],{},[23,10216,10217,10220],{},[70,10218,10219],{},"ls \u002Fmedia",": shows available mounted folders",[23,10222,10223,10226],{},[70,10224,10225],{},"ls \u002Fmedia\u002F\u003Cshared-folder>",": checks your course repo share",[23,10228,10229],{},"Permission denied is common the first time",[11,10231,10233,10237,10240,10243],{"id":10232,"level":14},"step-7-locate-share",[16,10234,10236],{"id":10235},"step-7-allow-shared-folder-access","Step 7: Allow Shared Folder Access",[108,10238,10239],{},"If the shared folder exists but says permission denied:",[540,10241],{"language":542,"src":10242},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-allow-shared-fold-07.sh",[20,10244,10245,10251,10257],{},[23,10246,10247,10250],{},[70,10248,10249],{},"vboxsf",": group allowed to read VirtualBox shared folders",[23,10252,10253,10256],{},[70,10254,10255],{},"$USER",": your Ubuntu login user for terminal access",[23,10258,10259],{},"Reboot applies the shared-folder support and new group membership",[11,10261,10263,10267,10269,10272,10289,10292],{"id":10262,"level":255},"step-7b-locate-share",[16,10264,10266],{"id":10265},"step-71-locate-the-shared-repo","Step 7.1: Locate The Shared Repo",[108,10268,10209],{},[540,10270],{"language":542,"src":10271},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-7-1-locate-the-shar-08.sh",[20,10273,10274,10280,10286],{},[23,10275,10276,10279],{},[70,10277,10278],{},"\u002Fmedia",": VirtualBox auto-mounted shared folders",[23,10281,10282,10285],{},[70,10283,10284],{},"\u003Cshared-folder>",": your shared course repo folder name",[23,10287,10288],{},"Use the folder that points to your repository",[108,10290,10291],{},"Expected repo folders:",[20,10293,10294,10298,10302,10306],{},[23,10295,10296],{},[70,10297,1637],{},[23,10299,10300],{},[70,10301,6094],{},[23,10303,10304],{},[70,10305,6097],{},[23,10307,10308],{},[70,10309,6100],{},[11,10311,10313,10317,10332],{"id":10312,"level":255},"step-7-2-shared-folder-check",[16,10314,10316],{"id":10315},"step-72-shared-folder-check","Step 7.2: Shared Folder Check",[20,10318,10319,10322,10329],{},[23,10320,10321],{},"Edit a small file from VS Code on host",[23,10323,397,10324,159,10326,10328],{},[70,10325,1626],{},[70,10327,1843],{}," inside Ubuntu",[23,10330,10331],{},"Confirm Ubuntu sees the same file content",[108,10333,10334],{},"If the file does not match, stop and fix the share before Apache setup",[11,10336,10338,10342,10344,10347],{"id":10337,"level":14},"step-8-install-apache-php-mysql",[16,10339,10341],{"id":10340},"step-8-install-apache-php-and-mysql","Step 8: Install Apache, PHP, And MySQL",[108,10343,10178],{},[540,10345],{"language":542,"src":10346},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-8-install-apache-ph-09.sh",[20,10348,10349,10355,10360,10366,10372,10378],{},[23,10350,10351,10354],{},[70,10352,10353],{},"apache2",": web server",[23,10356,10357,10359],{},[70,10358,851],{},": PHP runtime",[23,10361,10362,10365],{},[70,10363,10364],{},"libapache2-mod-php",": lets Apache execute PHP files",[23,10367,10368,10371],{},[70,10369,10370],{},"mysql-server",": local MySQL database server",[23,10373,10374,10377],{},[70,10375,10376],{},"php-mysql",": lets PHP connect to MySQL",[23,10379,397,10380,322,10382,10384],{},[70,10381,10077],{},[70,10383,10083],{}," first only if they have not been run recently",[11,10386,10388,10392,10399],{"id":10387,"level":255},"optional-swap-check",[16,10389,10391],{"id":10390},"optional-add-swap-if-swap-is-off","Optional: Add Swap If Swap Is Off",[108,10393,10394,10395,10398],{},"Ubuntu usually has swap already. Only add this if ",[70,10396,10397],{},"swapon --show"," prints nothing.",[261,10400,10401,10415],{"gap":263,"left-width":483,"right-width":483},[268,10402,10403,10406,10409,10412],{"v-slot:left":270},[108,10404,10405],{},"Check first:",[540,10407],{"language":542,"src":10408},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-10.sh",[108,10410,10411],{},"Add a small swap file only if swap is off:",[540,10413],{"language":542,"src":10414},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-add-swap-if-swa-11.sh",[268,10416,10417],{"v-slot:right":270},[20,10418,10419,10422,10427,10430],{},[23,10420,10421],{},"Swap gives Ubuntu emergency disk-backed memory",[23,10423,10424,10425],{},"It helps when installs or MySQL briefly need more than ",[70,10426,9020],{},[23,10428,10429],{},"It is slower than RAM, so it is not a performance upgrade",[23,10431,10432],{},"Do not run the setup again if swap already exists",[11,10434,10436,10440,10446],{"id":10435,"level":255},"optional-apache-low-memory",[16,10437,10439],{"id":10438},"optional-limit-apache-memory-use","Optional: Limit Apache Memory Use",[108,10441,10442,10443,10445],{},"Use this if the ",[70,10444,9020],{}," VM feels unstable or Apache starts too many PHP workers.",[261,10447,10448,10461],{"gap":263,"left-width":483,"right-width":483},[268,10449,10450,10453,10458],{"v-slot:left":270},[108,10451,10452],{},"Edit Apache prefork settings in:",[108,10454,10455],{},[70,10456,10457],{},"\u002Fetc\u002Fapache2\u002Fmods-available\u002Fmpm_prefork.conf",[540,10459],{"language":542,"src":10460},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-12.sh",[268,10462,10463,10466,10470],{"v-slot:right":270},[108,10464,10465],{},"Change the existing values to:",[540,10467],{"language":10468,"src":10469},"apache","\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-apache-me-13.txt",[20,10471,10472,10478,10481,10488],{},[23,10473,10474,10475],{},"Edit the existing lines inside ",[70,10476,10477],{},"\u003CIfModule mpm_prefork_module>",[23,10479,10480],{},"If a line is missing, add it inside that same block",[23,10482,10483,10484,10487],{},"Do not paste a second ",[70,10485,10486],{},"\u003CIfModule>"," block",[23,10489,10490],{},"Restart Apache after config changes",[11,10492,10494,10498,10504],{"id":10493,"level":255},"optional-mysql-low-memory",[16,10495,10497],{"id":10496},"optional-limit-mysql-memory-use","Optional: Limit MySQL Memory Use",[108,10499,10500,10501,10503],{},"Use this only if MySQL struggles on the ",[70,10502,9020],{}," VM.",[261,10505,10506,10519],{"gap":263,"left-width":483,"right-width":483},[268,10507,10508,10511,10516],{"v-slot:left":270},[108,10509,10510],{},"Edit MySQL server settings in:",[108,10512,10513],{},[70,10514,10515],{},"\u002Fetc\u002Fmysql\u002Fmysql.conf.d\u002Fmysqld.cnf",[540,10517],{"language":542,"src":10518},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-14.sh",[268,10520,10521,10527,10530],{"v-slot:right":270},[108,10522,10523,10524,2067],{},"Add or edit these under ",[70,10525,10526],{},"[mysqld]",[540,10528],{"language":6694,"src":10529},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Foptional-limit-mysql-mem-15.txt",[20,10531,10532,10538,10543,10546],{},[23,10533,10534,10535,10537],{},"Keep these under the existing ",[70,10536,10526],{}," heading",[23,10539,10540,10541,10537],{},"Do not create a second ",[70,10542,10526],{},[23,10544,10545],{},"If either setting already exists, edit it instead of adding a duplicate",[23,10547,10548],{},"Restart MySQL after config changes",[11,10550,10552,10555,10558,10561],{"id":10551,"level":255},"low-memory-diagnostics",[16,10553,10554],{"id":10551},"Low Memory Diagnostics",[108,10556,10557],{},"Run these after the minor tuning checks:",[540,10559],{"language":542,"src":10560},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Flow-memory-diagnostics-10.sh",[20,10562,10563,10569,10574,10580,10587],{},[23,10564,10565,10568],{},[70,10566,10567],{},"free -h",": shows RAM and swap",[23,10570,10571,10573],{},[70,10572,10397],{},": confirms whether swap is active",[23,10575,10576,10579],{},[70,10577,10578],{},"systemctl status",": checks whether Apache and MySQL are running",[23,10581,10582,10583,10586],{},"No output from the ",[70,10584,10585],{},"grep"," line is usually good",[23,10588,10589],{},"Do not tune randomly; change one setting, restart, then retest",[11,10591,10593,10597,10599,10602,10605,10608],{"id":10592,"level":14},"step-9-create-local-mysql-db",[16,10594,10596],{"id":10595},"step-9-create-a-local-mysql-database","Step 9: Create A Local MySQL Database",[108,10598,10178],{},[540,10600],{"language":542,"src":10601},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-11.sh",[108,10603,10604],{},"Then run in the MySQL prompt:",[540,10606],{"language":6100,"src":10607},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-9-create-a-local-my-12.sql",[20,10609,10610,10614,10617],{},[23,10611,10010,10612,10014],{},[70,10613,10013],{},[23,10615,10616],{},"Database name and username should match your UCID",[23,10618,10619],{},"Password is local-only unless your instructor says otherwise",[11,10621,10623,10626,10629,10642,10645,10651],{"id":10622,"level":14},"local-vs-remote-database",[16,10624,10625],{"id":10622},"Local Vs Remote Database",[108,10627,10628],{},"This MySQL database is only for local testing:",[20,10630,10631,10635,10637,10639],{},[23,10632,287,10633],{},[70,10634,8717],{},[23,10636,302],{},[23,10638,299],{},[23,10640,10641],{},"Password: your local password",[108,10643,10644],{},"Render uses the instructor-provided remote database connection string",[108,10646,10647,10648],{},"Get that string from ",[86,10649,313],{"href":313,"rel":10650},[90],[108,10652,10653],{},"After this lesson, you may optionally point local code at that remote database for extra testing",[11,10655,10657,10661,10663,10666,10668,10671,10674],{"id":10656,"level":14},"step-10-confirm-local-mysql",[16,10658,10660],{"id":10659},"step-10-confirm-local-mysql-login","Step 10: Confirm Local MySQL Login",[108,10662,10178],{},[540,10664],{"language":542,"src":10665},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-13.sh",[108,10667,5102],{},[540,10669],{"language":6100,"src":10670},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-10-confirm-local-my-14.sql",[108,10672,10673],{},"Expected:",[20,10675,10676,10682],{},[23,10677,10678,10681],{},[70,10679,10680],{},"SELECT DATABASE()"," returns your UCID",[23,10683,10684,10687],{},[70,10685,10686],{},"SHOW TABLES"," is empty or shows starter tables later",[11,10689,10691,10697,10700,10703,10706],{"id":10690,"level":14},"step-11-documentroot",[16,10692,10694,10695],{"id":10693},"step-11-point-apache-at-public_html","Step 11: Point Apache At ",[70,10696,1637],{},[108,10698,10699],{},"Apache should serve:",[540,10701],{"language":663,"src":10702},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-point-apache-at--15.txt",[108,10704,10705],{},"Do not serve the whole repo",[20,10707,10708,10717],{},[23,10709,10710,236,10712,1440,10714,10716],{},[70,10711,6094],{},[70,10713,6097],{},[70,10715,6100],{}," stay outside the web root",[23,10718,10719,10721],{},[70,10720,1637],{}," is the browser-facing folder",[11,10723,10725,10729,10732,10737,10739,10744,10747,10750],{"id":10724,"level":255},"apache-site-config",[16,10726,10728],{"id":10727},"step-111-apache-site-config","Step 11.1: Apache Site Config",[108,10730,10731],{},"Create or edit this Apache site config file inside Ubuntu:",[108,10733,10734],{},[70,10735,10736],{},"\u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[108,10738,631],{},[108,10740,10741],{},[70,10742,10743],{},"sudo nano \u002Fetc\u002Fapache2\u002Fsites-available\u002Fit202.conf",[108,10745,10746],{},"Add this content to that file:",[540,10748],{"language":10468,"src":10749},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-1-apache-site-co-16.txt",[20,10751,10752,10757,10763,10768],{},[23,10753,10010,10754,10756],{},[70,10755,10284],{}," with the actual shared folder name",[23,10758,10759,10760],{},"Save the file as ",[70,10761,10762],{},"it202.conf",[23,10764,10765,10766],{},"Apache listens on guest port ",[70,10767,8499],{},[23,10769,10770,10771],{},"Host browser reaches it through ",[70,10772,8575],{},[11,10774,10776,10780,10782,10785],{"id":10775,"level":255},"enable-site",[16,10777,10779],{"id":10778},"step-112-enable-the-site","Step 11.2: Enable The Site",[108,10781,10178],{},[540,10783],{"language":542,"src":10784},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-11-2-enable-the-sit-17.sh",[20,10786,10787,10793,10799,10805,10813,10819],{},[23,10788,10789,10792],{},[70,10790,10791],{},"a2ensite",": enable a site config",[23,10794,10795,10798],{},[70,10796,10797],{},"a2dissite",": disable a site config",[23,10800,10801,10804],{},[70,10802,10803],{},"www-data",": Apache's user for browser requests",[23,10806,10807,10808,6847,10810,10812],{},"Adding ",[70,10809,10803],{},[70,10811,10249],{}," lets Apache read the shared folder",[23,10814,10815,10818],{},[70,10816,10817],{},"configtest",": check syntax before reload",[23,10820,10821,10824],{},[70,10822,10823],{},"restart",": applies the Apache user group change",[11,10826,10828,10832,10835,10838,10841],{"id":10827,"level":14},"step-12-php-check-page",[16,10829,10831],{"id":10830},"step-12-create-a-php-check-page","Step 12: Create A PHP Check Page",[108,10833,10834],{},"Create this file on the host:",[540,10836],{"language":663,"src":10837},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-18.txt",[108,10839,10840],{},"Example content:",[540,10842],{"language":851,"src":10843},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Fstep-12-create-a-php-che-19.php",[11,10845,10847,10850,10853,10856,10858],{"id":10846,"level":14},"final-browser-check",[16,10848,10849],{"id":10846},"Final Browser Check",[108,10851,10852],{},"Open from host browser:",[540,10854],{"language":663,"src":10855},"\u002Fgenerated-snippets\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox\u002Ffinal-browser-check-20.txt",[108,10857,10673],{},[20,10859,10860,10863,10866,10869],{},[23,10861,10862],{},"Message appears",[23,10864,10865],{},"Time appears",[23,10867,10868],{},"PHP code is not shown as raw text",[23,10870,10871],{},"Editing the file on host changes output after refresh",[11,10873,10875,10878],{"id":10874,"level":14},"common-problems",[16,10876,10877],{"id":10874},"Common Problems",[20,10879,10880,10883,10886,10891,10894,10907,10917],{},[23,10881,10882],{},"Browser timeout: missing or wrong port-forwarding rule",[23,10884,10885],{},"Connection refused: Apache not running",[23,10887,10888,10889],{},"No internet in VM: check Adapter 1 is still ",[70,10890,9894],{},[23,10892,10893],{},"Shared folder missing: check Auto-mount and guest utilities",[23,10895,10896,10897,10900,10901,10903,10904,10906],{},"Browser shows ",[70,10898,10899],{},"403 Forbidden",": confirm ",[70,10902,10803],{}," is in ",[70,10905,10249],{},", then restart Apache or reboot",[23,10908,10909,10910,10913,10914,10916],{},"Permission denied on ",[70,10911,10912],{},"\u002Fmedia\u002Fsf_...",": confirm your Ubuntu user is in ",[70,10915,10249],{}," and reboot",[23,10918,10919],{},"Raw PHP code: PHP module not running through Apache",[11,10921,10923,10926,10929],{"id":10922,"level":14},"recovery-routine",[16,10924,10925],{"id":10922},"Recovery Routine",[108,10927,10928],{},"Check in this order:",[410,10930,10931,10934,10940,10946,10951,10959,10966,10972,10977,10986],{},[23,10932,10933],{},"VM is running",[23,10935,10936,10939],{},[70,10937,10938],{},"ping github.com"," works inside Ubuntu",[23,10941,10942,10945],{},[70,10943,10944],{},"ssh username@localhost"," works from host",[23,10947,10948,10950],{},[70,10949,10225],{}," shows the shared repo",[23,10952,10953,10956,10957],{},[70,10954,10955],{},"groups"," includes ",[70,10958,10249],{},[23,10960,10961,10956,10964],{},[70,10962,10963],{},"id www-data",[70,10965,10249],{},[23,10967,10968,10971],{},[70,10969,10970],{},"sudo systemctl status apache2"," is active",[23,10973,10974,10971],{},[70,10975,10976],{},"sudo systemctl status mysql",[23,10978,10979,10982,10983],{},[70,10980,10981],{},"sudo apache2ctl configtest"," says ",[70,10984,10985],{},"Syntax OK",[23,10987,10988,10991],{},[70,10989,10990],{},"http:\u002F\u002Flocalhost:3000\u002Fsystem\u002Fvm-check.php"," loads from the host browser",[11,10993,10994,10996],{"id":724,"level":14},[16,10995,727],{"id":724},[261,10997,10998,11039],{"gap":263,"left-width":483,"right-width":483},[268,10999,11000,11002,11008,11017,11022,11028,11034],{"v-slot:left":270},[179,11001,735],{"id":734},[108,11003,11004,11007],{},[963,11005,11006],{},"VM"," - separate computer running inside your host computer",[108,11009,11010,11013,11014,11016],{},[963,11011,11012],{},"Port forwarding"," - host ",[70,11015,8717],{}," traffic routed into the VM",[108,11018,11019,11021],{},[963,11020,10249],{}," - VirtualBox shared-folder permission group",[108,11023,11024,11027],{},[963,11025,11026],{},"Guest utilities"," - VirtualBox tools that help shared folders work inside Ubuntu",[108,11029,11030,11033],{},[963,11031,11032],{},"DocumentRoot"," - folder Apache serves to browsers",[108,11035,11036,11038],{},[963,11037,9894],{}," - VM network mode that gives the VM outbound internet access",[268,11040,11041,11043],{"v-slot:right":270},[179,11042,755],{"id":754},[20,11044,11045,11051,11058,11065,11072,11079,11085],{},[23,11046,11047],{},[86,11048,11050],{"href":8641,"rel":11049},[90],"VirtualBox Downloads",[23,11052,11053],{},[86,11054,11057],{"href":11055,"rel":11056},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002FIntroduction.html",[90],"VirtualBox Manual: Host And Guest Combinations",[23,11059,11060],{},[86,11061,11064],{"href":11062,"rel":11063},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Finstallation.html",[90],"VirtualBox Manual: Installation",[23,11066,11067],{},[86,11068,11071],{"href":11069,"rel":11070},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fsharedfolders.html",[90],"VirtualBox Manual: Shared Folders",[23,11073,11074],{},[86,11075,11078],{"href":11076,"rel":11077},"https:\u002F\u002Fdocs.oracle.com\u002Fen\u002Fvirtualization\u002Fvirtualbox\u002F7.2\u002Fuser\u002Fnetworkingdetails.html#network_nat_service",[90],"VirtualBox Manual: NAT Port Forwarding",[23,11080,11081],{},[86,11082,11084],{"href":8659,"rel":11083},[90],"Ubuntu Server: Installer",[23,11086,11087],{},[86,11088,11091],{"href":11089,"rel":11090},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Fserver\u002Fhow-to\u002Fsecurity\u002Fopenssh-server\u002F",[90],"Ubuntu Server: OpenSSH Server",[11,11093,11094,11096,11098],{"id":781,"level":14},[16,11095,784],{"id":781},[108,11097,2325],{},[20,11099,11100,11103,11106,11109,11112,11117],{},[23,11101,11102],{},"Pick the correct Ubuntu ISO for your host CPU",[23,11104,11105],{},"Configure NAT port forwarding",[23,11107,11108],{},"Connect to Ubuntu with SSH",[23,11110,11111],{},"Find the VirtualBox shared repo",[23,11113,11114,11115],{},"Configure Apache to serve ",[70,11116,1637],{},[23,11118,11119],{},"Create a local MySQL database and user named after your UCID",{"title":270,"searchDepth":424,"depth":424,"links":11121},[11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11180,11181,11182,11183,11184,11185,11186,11187],{"id":8521,"depth":424,"text":8513},{"id":8547,"depth":424,"text":8550},{"id":8592,"depth":424,"text":8595},{"id":1452,"depth":424,"text":1455},{"id":8697,"depth":424,"text":8700},{"id":8732,"depth":424,"text":8733},{"id":8756,"depth":424,"text":8759},{"id":8788,"depth":424,"text":8791},{"id":8814,"depth":424,"text":8817},{"id":8843,"depth":424,"text":8846},{"id":8875,"depth":424,"text":8876},{"id":8899,"depth":424,"text":8902},{"id":8930,"depth":424,"text":8933},{"id":8961,"depth":424,"text":8962},{"id":8997,"depth":424,"text":8998},{"id":9059,"depth":424,"text":9062},{"id":9094,"depth":424,"text":9097},{"id":9140,"depth":424,"text":9143},{"id":9183,"depth":424,"text":9186},{"id":9227,"depth":424,"text":9230},{"id":9277,"depth":424,"text":9278},{"id":9340,"depth":424,"text":9341},{"id":9376,"depth":424,"text":9377},{"id":9411,"depth":424,"text":9412},{"id":9448,"depth":424,"text":9449},{"id":9481,"depth":424,"text":9482},{"id":9518,"depth":424,"text":9519},{"id":9551,"depth":424,"text":9552},{"id":9581,"depth":424,"text":9582},{"id":9611,"depth":424,"text":9612},{"id":9641,"depth":424,"text":9642},{"id":9671,"depth":424,"text":9672},{"id":9701,"depth":424,"text":9702},{"id":9735,"depth":424,"text":9736},{"id":9767,"depth":424,"text":9768},{"id":9799,"depth":424,"text":9800},{"id":9831,"depth":424,"text":9832},{"id":9882,"depth":424,"text":9883},{"id":9925,"depth":424,"text":9926},{"id":9951,"depth":424,"text":9952},{"id":9992,"depth":424,"text":9993},{"id":10044,"depth":424,"text":10045},{"id":10123,"depth":424,"text":10124},{"id":10174,"depth":424,"text":10175},{"id":10205,"depth":424,"text":10206},{"id":10235,"depth":424,"text":10236},{"id":10265,"depth":424,"text":10266},{"id":10315,"depth":424,"text":10316},{"id":10340,"depth":424,"text":10341},{"id":10390,"depth":424,"text":10391},{"id":10438,"depth":424,"text":10439},{"id":10496,"depth":424,"text":10497},{"id":10551,"depth":424,"text":10554},{"id":10595,"depth":424,"text":10596},{"id":10622,"depth":424,"text":10625},{"id":10659,"depth":424,"text":10660},{"id":10693,"depth":424,"text":11179},"Step 11: Point Apache At public_html",{"id":10727,"depth":424,"text":10728},{"id":10778,"depth":424,"text":10779},{"id":10830,"depth":424,"text":10831},{"id":10846,"depth":424,"text":10849},{"id":10874,"depth":424,"text":10877},{"id":10922,"depth":424,"text":10925},{"id":724,"depth":424,"text":727},{"id":781,"depth":424,"text":784},"Build the local Ubuntu VM path with VirtualBox, Apache, PHP, MySQL, SSH, and shared folders.","Face-to-face class of about 40 students; includes VirtualBox install differences, CPU\u002FISO selection, networking, SSH, shared folders, Apache\u002FPHP\u002FMySQL, browser checks, and beginner troubleshooting.","25","95","120",{},"\u002Finternet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",{"title":8513,"description":11188},"internet-applications\u002Fpresentations\u002F01-git-github-and-course-workflow\u002F09-local-ubuntu-web-server-virtualbox",[11198,11199,10468,11200,11201],"virtualbox","ubuntu","mysql","vm","1:06:16","ArTDIgihfd4","https:\u002F\u002Fyoutu.be\u002FArTDIgihfd4","IT202 VirtualBox and VM Setup","CNlzYvIiYNPSzbQ6tvCdcnJLlvvGSGmurOGWR_mSnms",[],1780581681278]