<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vatsalya Goel</title>
    <description>The latest articles on DEV Community by Vatsalya Goel (@vatsalyagoel).</description>
    <link>https://dev.to/vatsalyagoel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F169554%2Fbd427d2e-f79a-4fdf-b1a4-e79dd0bfbcec.jpeg</url>
      <title>DEV Community: Vatsalya Goel</title>
      <link>https://dev.to/vatsalyagoel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vatsalyagoel"/>
    <language>en</language>
    <item>
      <title>Rewriting Git history : Being opinionated about Git</title>
      <dc:creator>Vatsalya Goel</dc:creator>
      <pubDate>Tue, 10 Jul 2018 14:39:56 +0000</pubDate>
      <link>https://dev.to/vatsalyagoel/rewriting-git-history-being-opinionated-about-git-2bn1</link>
      <guid>https://dev.to/vatsalyagoel/rewriting-git-history-being-opinionated-about-git-2bn1</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fbanner.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fbanner.PNG" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my short development career I've heard many different opinions on how to use Git the right way. There are a lot of times when the answer is "it depends" and can be daunting for a new user getting started on Git. I've picked on some tips to make my source control habits nicer which I'll mention below. Everyone's workflow is different but here are my tips on maintaining source control so when a new developer joins your team they won't be confused on where to start.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learn the &lt;code&gt;git&lt;/code&gt; CLI
&lt;/h1&gt;

&lt;p&gt;Don't get me wrong, Git GUIs are nice and offer a lot of features that will feel very clunky if you used the cli such as comparing &lt;a href="https://git-scm.com/docs/git-diff" rel="noopener noreferrer"&gt;diffs&lt;/a&gt;, reversing &lt;a href="http://www.gnu.org/software/diffutils/manual/html_node/Hunks.html" rel="noopener noreferrer"&gt;hunks&lt;/a&gt; or just looking at the history. A GUI will be sufficient if all you're looking to do is commit and push. Git has a lot of other tools to offer and the cli is your friend when working with the history and not the content itself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trunk based development
&lt;/h1&gt;

&lt;p&gt;To give a bit of context the &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;trunk&lt;/code&gt; is where the production ready code should live and is the branch that is checked-out by default if you clone a new repository. There have been multiple occasions in which I've cloned a git repo looked at the history and there is a &lt;code&gt;develop&lt;/code&gt; or a &lt;code&gt;release&lt;/code&gt; branch which is 100 commits ahead of master which was last updated 2 months ago with code that doesn't even compile anymore due to outdated dependencies or no historical context of which branch I need to be using.&lt;/p&gt;

&lt;p&gt;It raises so many questions such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Are we not using master anymore?&lt;/li&gt;
&lt;li&gt;Is the branch deprecated?&lt;/li&gt;
&lt;li&gt;Do I just reset master to the current &lt;code&gt;head&lt;/code&gt;?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://trunkbaseddevelopment.com/" rel="noopener noreferrer"&gt;Trunk Based Development&lt;/a&gt; is a workflow defined as "&lt;em&gt;a source-control branching model, where developers collaborate on code in a single branch called ‘trunk’, resist any pressure to create other long-lived development branches by employing documented techniques. They therefore avoid merge hell, do not break the build, and live happily ever after.&lt;/em&gt;" So create short lived feature branches that are integrated often so any future developers who join the project remain happy.&lt;/p&gt;

&lt;p&gt;If you do want to keep track of releases, &lt;a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging" rel="noopener noreferrer"&gt;tag&lt;/a&gt; the commits that you have releases on. That is what tags are for.&lt;/p&gt;

&lt;h1&gt;
  
  
  Never commit to &lt;code&gt;master&lt;/code&gt; directly
&lt;/h1&gt;

&lt;p&gt;Following up on trunk based development, don't commit to master directly. Protect your master branch from abuses such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"fixed typo"&lt;/li&gt;
&lt;li&gt;"Hack-v2"&lt;/li&gt;
&lt;li&gt;"resolving merge conflict"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make your changes on &lt;code&gt;hotfix/typo&lt;/code&gt; or &lt;code&gt;feature/add-this-feature&lt;/code&gt; create a &lt;a href="https://help.github.com/articles/about-pull-requests/" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; and let other people review your code. Don't be scared, code reviews are nice. This also lets you run Tests your CI before it is merged so you can fix issues that may have been caused due to your change. If you use a remote source repository, you can physically protect your branch so no one can push to the source of truth.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://help.github.com/articles/configuring-protected-branches/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/vsts/git/branch-policies?view=vsts" rel="noopener noreferrer"&gt;VSTS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Merge vs Rebase
&lt;/h1&gt;

&lt;p&gt;Here comes the most discussed question about what is the right way of doing things.&lt;/p&gt;

&lt;p&gt;Proof?&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmerge-vs-rebase.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmerge-vs-rebase.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Always rebase instead of merge. It makes your history look nicer. Let the pull request create a merge commit into master. That is the only time you want a merge in your code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull origin master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout feature/feature-youre-working-on&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push -f origin feature/feature-youre-working-on&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;git push -f&lt;/code&gt; AKA force push is used to overwrite the remote branch if there are any changes on your history such as you rebasing.&lt;br&gt;&lt;br&gt;
Note: This flag can cause the remote repository to lose commits; use it with care.&lt;/p&gt;

&lt;p&gt;Now you may say isn't force push bad. If no one else is working on the same branch as you i.e. no long running branches then you shouldn't have to worry about force push. Knowing changes on your own branch and manipulating it is your decision and since master is protected you can't modify any release.&lt;/p&gt;

&lt;h1&gt;
  
  
  Commit messages
&lt;/h1&gt;

&lt;p&gt;Write meaningful commit messages. Commit messages are important and can help new developers understand context of what changes were done. If using a backlog management system, link your commits to work items in your backlogs. Take advantage of the fact that you have a title and a body in your message. Be concise and everyone will love you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tools and useful commands
&lt;/h1&gt;

&lt;p&gt;Throughout my journey with git, I have picked up commands that help me learn git, rewrite the history and make my life easier on a day to day basis.&lt;/p&gt;

&lt;p&gt;Before we get started on commands, get this tool &lt;a href="https://github.com/Readify/GitViz/releases" rel="noopener noreferrer"&gt;GitViz&lt;/a&gt;. You can put the path of any git repository and it will give you a live visual representation of the history and current state of the repository. It is great for a playground but don't use it as a full git UI tool.&lt;/p&gt;

&lt;p&gt;I would also recommend cloning this &lt;a href="https://github.com/vatsalyagoel/GitPlayground" rel="noopener noreferrer"&gt;playground&lt;/a&gt; git project that I created to simulate different scenarios that you may encounter. Create a blank project on GitHub and change the origin to the new blank repository by running &lt;code&gt;git remote set-url origin {new repo url}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Alternatively you can you an in-browser &lt;a href="https://git-school.github.io/visualizing-git/" rel="noopener noreferrer"&gt;tool&lt;/a&gt; from GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge to resolve conflicts
&lt;/h2&gt;

&lt;p&gt;In this scenario we cover a change done on a feature branch that results in a merge conflict to master. To fix the conflict via a merge back:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull origin master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout feature/merge-conflict&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;resolve merge conflict&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge --continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push origin feature/merge-conflict&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;this creates a commit &lt;code&gt;Merge branch 'master' into feature/merge-conflict&lt;/code&gt; with the merge conflict resolution and if the branch is then merged back into master it starts to look very ugly&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmerge-back.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmerge-back.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rebase to resolve conflicts
&lt;/h2&gt;

&lt;p&gt;An alternative to above is to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull origin master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout feature/rebase-conflict&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;resolve merge conflict&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase --continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push -f origin feature/rebase-conflict&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This changes the parent of your branch to the latest master and gives you a straight path to a pull request.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-then-merge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-then-merge.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactive Rebase
&lt;/h2&gt;

&lt;p&gt;Sometimes just resolving merge conflicts isn't enough. I am a big proponent of committing often however this can cause my feature branch to have many commits that won't make individual logical sense for reviewers to review.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmultiple-small-commits.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fmultiple-small-commits.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example we will use interactive rebase and see how we can rewrite the branch history and group multiple commits into one logical commit so that reviewers have an easier time reviewing your pull request.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull origin master&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout feature/rebase-interactive&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase -i master&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will give you an output like this:&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-sample.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-sample.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each pick in the above image is a commit and as you can see, there are many small commits that I probably want to group into one commit&lt;br&gt;&lt;br&gt;
we can edit the above output to change &lt;code&gt;pick&lt;/code&gt; into &lt;code&gt;fixup&lt;/code&gt; which deletes the commit message and amends the changes into the commit above. Saving the file and exiting will apply the changes&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-fixup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-fixup.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git push -f origin feature/rebase-interactive&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This results in a history like this&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fgrouped-commits.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fgrouped-commits.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will notice that even though the changes are merged the commit message is still add two so how do we fix the commit message. Use Rebase again&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git checkout feature/rebase-interactive&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase -i master&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This time instead of using &lt;code&gt;fixup&lt;/code&gt; we use &lt;code&gt;reword&lt;/code&gt;&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-reword.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-interactive-reword.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Saving and quitting the file gives us another terminal output with the commit&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-change-two.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-change-two.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets change &lt;code&gt;add two&lt;/code&gt; to &lt;code&gt;add two, three and four&lt;/code&gt;&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-add-twothreefour.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Frebase-add-twothreefour.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git push -f origin feature/rebase-interactive&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally your history will look like:&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fgrouped-reworded-commits.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvatsalyagoel.com%2Fcontent%2Fimages%2F2018%2F07%2Fgrouped-reworded-commits.png" alt="Rewriting Git history : Being opinionated about Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion Git is a very opinionated topic and everyone is comfortable using git in a certain way. I hope that I was able to see the benefits of using certain git workflows to make your development life easier and keep the sanity of the person who takes on the source repository after you.&lt;/p&gt;

</description>
      <category>git</category>
      <category>workflows</category>
    </item>
    <item>
      <title>Setting up a public web server using a Raspberry Pi 3</title>
      <dc:creator>Vatsalya Goel</dc:creator>
      <pubDate>Thu, 12 Oct 2017 08:41:48 +0000</pubDate>
      <link>https://dev.to/vatsalyagoel/setting-up-a-public-web-server-using-a-raspberry-pi-3-3n89</link>
      <guid>https://dev.to/vatsalyagoel/setting-up-a-public-web-server-using-a-raspberry-pi-3-3n89</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pNDUfe6I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2018/06/Raspberry_PI.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pNDUfe6I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2018/06/Raspberry_PI.jpeg" alt="Setting up a public web server using a Raspberry Pi 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Very recently, I got hold of a Raspberry Pi 3 Model B. With the desire to setup a home automation system I first wanted to see if I could access the Pi publicly through my home's internet connection. This would have been the easiest task by just port forwarding if not for my ISP locking down the router behind a NAT-1 switch. This crushed my dreams of being able to do what I wanted.&lt;/p&gt;

&lt;p&gt;I started looking at online solutions to securely tunnel from the Pi to the internet and obtain a publicly accessible domain. This is where I came across &lt;a href="https://ngrok.com/"&gt;Ngrok&lt;/a&gt;, a service that allows you to tunnel a port on a machine and expose it publicly. Their use case surrounds demos and testing without deployments. However I tried to re-purpose it to setup a webserver on my Raspberry Pi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Raspberry Pi
&lt;/h2&gt;

&lt;p&gt;What do we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Raspberry Pi 3&lt;/li&gt;
&lt;li&gt;A micro SD card with at least 8 GB space (16 GB recommended)&lt;/li&gt;
&lt;li&gt;An SD card reader&lt;/li&gt;
&lt;li&gt;Raspbian OS which can be downloaded from &lt;a href="https://www.raspberrypi.org/downloads/raspbian/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Etcher which can be downloaded from &lt;a href="https://etcher.io/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An internet connection (Wireless or wired)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Download &lt;code&gt;Raspbian Stretch with Desktop&lt;/code&gt; from the raspbian download page. Plug the micro SD card into the reader. Unzip the Raspbian image from the download and use Etcher to write the image to the SD card.&lt;/p&gt;

&lt;p&gt;Plug the micro SD card into the Pi and power it on. On the first boot you have no way of remotely connecting to the Pi. To configure remote access, plug the Pi into a monitor using the HDMI port. Connect a mouse and keyboard in order to configure the system. Go to &lt;code&gt;Menu &amp;gt; Preferences &amp;gt; Raspberry Pi Configuration&lt;/code&gt; and under the &lt;code&gt;localisation&lt;/code&gt; tab configure your Timezone, Locale and Keyboard layout. In needed to do this because the default region was set to UK and the keyboard layout wasn't the standard one I used. Go to the &lt;code&gt;Interfaces&lt;/code&gt; tab and enable &lt;code&gt;SSH&lt;/code&gt; and &lt;code&gt;VNC&lt;/code&gt;. This is so that you can remotely access the Pi without having any peripherals connected to it.&lt;/p&gt;

&lt;p&gt;Open a new terminal session and run &lt;code&gt;passwd&lt;/code&gt; in order to change the password. the default password is &lt;code&gt;raspberry&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring remote access
&lt;/h2&gt;

&lt;p&gt;Open a new terminal session and run &lt;code&gt;ifconfig&lt;/code&gt; and note down the IP address&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l3s9yFIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/ifconfig.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l3s9yFIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/ifconfig.PNG" alt="Setting up a public web server using a Raspberry Pi 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the following commands:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get update
$ sudo apt-get install realvnc-vnc-server
$ reboot
$ sudo systemctl enable vncserver-x11-serviced.service
$ sudo systemctl start vncserver-x11-serviced.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This should now setup remote access to your Raspberry Pi both graphical and terminal. Now you can go ahead and disconnect any peripherals you dont need connected.&lt;/p&gt;

&lt;p&gt;To connect to the Raspberry Pi graphically, download &lt;a href="https://www.realvnc.com/en/connect/download/viewer/"&gt;RealVNC Viewer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start VNC Viewer. Go to &lt;code&gt;File &amp;gt; New Connection&lt;/code&gt; Enter the above noted IP in the &lt;code&gt;VNC server&lt;/code&gt; field and give the Pi friendly name you can remember. Connect to the pi by double clicking on the new system you see on the dashboard. You should see a window like this.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g8ZhCXS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/vncViewer-1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g8ZhCXS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/vncViewer-1.PNG" alt="Setting up a public web server using a Raspberry Pi 3"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Enter &lt;code&gt;pi&lt;/code&gt; as the username and the password you set earlier as the password.&lt;/p&gt;

&lt;p&gt;You should now have a remote connection to the Pi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a web server
&lt;/h2&gt;

&lt;p&gt;For this task I decided to use Nginx due to it's lightweight nature. You can decide to use Apache if you do need to.&lt;/p&gt;

&lt;p&gt;To setup Nginx:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get install nginx
$ sudo systemctl enable nginx.service
$ sudo systemctl start nginx.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Browse to 127.0.0.1 in the browser within the Raspberry Pi and you should see a &lt;code&gt;Welcome to Nginx&lt;/code&gt; page.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OluS3D0g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/welcome-to-nginx-window-5x3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OluS3D0g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/welcome-to-nginx-window-5x3.png" alt="Setting up a public web server using a Raspberry Pi 3"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
To change the contents of the site, navigate to &lt;code&gt;/var/www/nginx&lt;/code&gt; and change the contents to the site you want to deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the site publicly accessible
&lt;/h2&gt;

&lt;p&gt;Now that we have our web server setup, we want to make it publicly accessible. This is where Ngrok comes in. Go to &lt;a href="https://ngrok.com"&gt;https://ngrok.com&lt;/a&gt; and register for and account. Note down the authtoken they give you. This will be used to setup the tunnel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ngrok.com/download"&gt;Download&lt;/a&gt; and install the Linux ARM version of Ngrok by running the following commands&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd /tmp 
$ wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip
$ sudo mkdir /etc/ngrok
$ unzip ./ngrok-stable-linux-arm.zip -d /etc/ngrok/
$ rm ./ngrok-stable-linux-arm.zip
$ ln -s /etc/ngrok/ngrok /usr/local/bin/ngrok
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create a new file &lt;code&gt;~/.ngrok2/ngrok.yml&lt;/code&gt; with the content below. This is the configuration file Ngrok looks at to begin tunneling. If you want to protect access to the site you can add an auth option &lt;code&gt;auth: "username:password"&lt;/code&gt; and this will protect your site via basic auth&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;authtoken: your-auth-token
tunnels:
  pi:
    proto: http
    addr: 80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once we have Ngrok configured, we need to set it up to run as a service. This is so that we don't need to keep a terminal session running.&lt;/p&gt;

&lt;p&gt;Create a new file &lt;code&gt;lib/systemd/system/ngrok.service&lt;/code&gt; with &lt;code&gt;root&lt;/code&gt; permissions.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Ngrok
After=multi-user.target

[Service]
Type=simple
ExecStart=/etc/ngrok/ngrok start -config /home/ **yourusername** /.ngrok2/ngrok.yml --all
Restart=on-abort

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To start the service&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ systemctl daemon-reload
$ sudo systemctl enable ngrok.service
$ sudo systemctl start ngrok.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Navigate to &lt;code&gt;http://127.0.0.1:4040/status&lt;/code&gt; and you should see the name of your ngrok domain.&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xkAfCq0f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/ngrok-status.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xkAfCq0f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://vatsalyagoel.com/content/images/2017/10/ngrok-status.PNG" alt="Setting up a public web server using a Raspberry Pi 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do want to setup a custom domain, it is only available on a paid plan. Review the pricing and if you find it useful, choose the plan that best suits you.&lt;/p&gt;

&lt;p&gt;Navigate to the URL you obtained from the dashboard. Congratulations! You now have a public web server on a Raspberry Pi.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
    </item>
  </channel>
</rss>
