<?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: Manuel Castellin</title>
    <description>The latest articles on DEV Community by Manuel Castellin (@mcastellin).</description>
    <link>https://dev.to/mcastellin</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%2F473261%2F7fca7900-b02c-45f1-b22b-33b089d3f600.jpg</url>
      <title>DEV Community: Manuel Castellin</title>
      <link>https://dev.to/mcastellin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mcastellin"/>
    <language>en</language>
    <item>
      <title>SnykCon - Making Sense of Container Security with Snyk CLI and GitHub Actions</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Thu, 22 Oct 2020 19:51:27 +0000</pubDate>
      <link>https://dev.to/mcastellin/snykcon-making-sense-of-container-security-with-snyk-cli-and-github-actions-phc</link>
      <guid>https://dev.to/mcastellin/snykcon-making-sense-of-container-security-with-snyk-cli-and-github-actions-phc</guid>
      <description>&lt;p&gt;I'm so excited I've participated in &lt;strong&gt;SnykCon 2020&lt;/strong&gt;! 🔥&lt;br&gt;
Listening to the talks lit a fire in me, and I really want to take container security seriously from now on, knowing how much easier it is today with tools like Snyk 🚀&lt;/p&gt;
&lt;h2&gt;
  
  
  But after running a container scan...
&lt;/h2&gt;

&lt;p&gt;... on a couple of very simple projects, well, this is not the result I was expecting: 🤯🤯🤯&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs5wf259u5rrp5n81zomz.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs5wf259u5rrp5n81zomz.png" alt="Overwhelming amount of issues"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was literally an &lt;em&gt;"Hello World!"&lt;/em&gt; type of project, what is going to happen if I scan a real project? &lt;strong&gt;How do I start making sense of this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me do a quick introduction and then I'll show you how I practically approached this problem 😉&lt;/p&gt;
&lt;h1&gt;
  
  
  A modern approach to security - DevSecOps
&lt;/h1&gt;

&lt;p&gt;As I learned from this year's conference, &lt;strong&gt;finding vulnerabilities early on in the software development cycle&lt;/strong&gt; is paramount in this day and age.&lt;/p&gt;

&lt;p&gt;With the adoption of &lt;em&gt;Continuous Delivery&lt;/em&gt;, hence shorter release cycles, &lt;strong&gt;we can no longer afford to wait for a team of security experts to validate every release&lt;/strong&gt;. New code will already be running in production by the time they complete their audit!&lt;/p&gt;

&lt;p&gt;Also, developers are the best people that can contextualize the vulnerabilities, and take action to fix them. 👨🏻‍💻&lt;/p&gt;
&lt;h2&gt;
  
  
  Shifting the responsibility towards developers
&lt;/h2&gt;

&lt;p&gt;Ok, this is a nice concept, &lt;strong&gt;developers are now responsible for security too&lt;/strong&gt;! But hold on a sec, they're developers! How can we expect them to do their job, and also monitor their software for vulnerabilities every day?&lt;/p&gt;

&lt;p&gt;This is where I think people at Snyk have done a great job. Their tools are focused on helping developers with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identifying vulnerabilities as &lt;strong&gt;early as in the developer's laptop&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;providing &lt;strong&gt;command-line tools&lt;/strong&gt; that can be &lt;strong&gt;integrated into CI/CD workflows&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;monitoring generated artifacts to &lt;strong&gt;proactively notify the team when new vulnerabilities are discovered&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;advise on actions to fix vulnerabilities&lt;/strong&gt; directly in the CLI for developers to see&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  My experience with Snyk Container scan
&lt;/h1&gt;

&lt;p&gt;Given that &lt;strong&gt;there's no such thing as absolute security&lt;/strong&gt;, this is the process I followed to get as close as I could for my demo container.&lt;/p&gt;

&lt;p&gt;If you want to have a look at the repository, you can find it &lt;a href="https://github.com/mcastellin/snyk-container-demo" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It's a simple &lt;em&gt;"Hello, World!"&lt;/em&gt; Python project, that, when I started, had &lt;strong&gt;a whopping 267 vulnerabilities&lt;/strong&gt;!&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 0 - creating a Snyk account
&lt;/h2&gt;

&lt;p&gt;The first thing to do is to create a Snyk account. This is required to start using the CLI tools from your development machine. See below, &lt;strong&gt;you just need to authorize the app with one of your existing accounts&lt;/strong&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyjzz5fjwwrbcr1kacydt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyjzz5fjwwrbcr1kacydt.png" alt="Create Snyk account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the account, &lt;strong&gt;Snyk will generate your personal API token&lt;/strong&gt;. This is needed to use the CLI tools from command-line and from your CI/CD workflow.&lt;/p&gt;

&lt;p&gt;If you already have an account, you'll find the token under &lt;em&gt;Your Name &amp;gt; General Settings &amp;gt; API Token&lt;/em&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4lguuibhsdfxye6p4wa7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4lguuibhsdfxye6p4wa7.png" alt="API token settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install the CLI tools with &lt;code&gt;npm&lt;/code&gt; and &lt;strong&gt;authenticate with your token&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Snyk CLI with npm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; snyk

&lt;span class="c"&gt;# Authenticate with your Snyk account&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; snyk auth &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;YOUR_API_TOKEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're now ready to scan our project! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - start from the development machine
&lt;/h2&gt;

&lt;p&gt;As I learned in the conference, the best way is to start in your development machine using Snyk CLI.&lt;/p&gt;

&lt;p&gt;First I wanted to make sure my python dependencies are clean from vulnerabilities. I'll do that directly from the command-line by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; snyk &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8z2vliyla2spb0977zmc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8z2vliyla2spb0977zmc.png" alt="snyk test command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it immediately found an issue with my &lt;code&gt;requirements.txt&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;What's cool about this, is that Snyk tells me that the vulnerability in &lt;code&gt;sqlalchemy@1.3.17&lt;/code&gt; has been resolved in a later version of the package, so I will just upgrade it to the suggested version &lt;code&gt;sqlalchemy@1.3.19&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Container image scanning
&lt;/h3&gt;

&lt;p&gt;Next, I want to &lt;strong&gt;run a container scan to make sure my image has as little vulnerabilities as possible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To do that, I first need to build the image, and then I can immediately scan it from the command line with &lt;code&gt;snyk container test&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; snyk container &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Dockerfile snyk-container-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the &lt;code&gt;--file=Dockerfile&lt;/code&gt; we can tell Snyk which Dockerfile generated the &lt;code&gt;snyk-container-demo&lt;/code&gt; image. This way we'll be able to &lt;strong&gt;get more accurate suggestions&lt;/strong&gt; from the advisor.&lt;/p&gt;

&lt;p&gt;And then I started to cry 😭&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbkmh6vkf0woqtamlhfbx.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbkmh6vkf0woqtamlhfbx.png" alt="total issues first report"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Stay calm and keep reading
&lt;/h3&gt;

&lt;p&gt;This is what I told myself when I first read this report. Despite having soo many issues reported (267 to be exact), the report is also &lt;strong&gt;suggesting alternative images&lt;/strong&gt; to the one I am currently using for the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Recommendations &lt;span class="k"&gt;for &lt;/span&gt;base image upgrade:

Alternative image types
Base Image                  Vulnerabilities  Severity
python:3.9.0rc1-slim        73               17 high, 12 medium, 44 low
python:3.9.0b5-slim-buster  73               17 high, 12 medium, 44 low
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty nice! I can see that &lt;strong&gt;the &lt;code&gt;-slim&lt;/code&gt; and &lt;code&gt;-slim-buster&lt;/code&gt; versions of my base image have fewer vulnerabilities&lt;/strong&gt;. So next thing I'll do is changing my &lt;code&gt;Dockerfile&lt;/code&gt; to use one of those.&lt;/p&gt;

&lt;h3&gt;
  
  
  And after applying the suggestion...
&lt;/h3&gt;

&lt;p&gt;... I was glad to see that the number of vulnerabilities found was drastically reduced!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhrcogth3l5j51o70nj0l.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhrcogth3l5j51o70nj0l.png" alt="reduced vulnerabilities second scan"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this report, Snyk is also telling me that I'm currently running on &lt;strong&gt;the most secure version of the selected base image&lt;/strong&gt;, remember, &lt;em&gt;there's no such thing as absolute security&lt;/em&gt; 😅&lt;/p&gt;

&lt;p&gt;Being happy with the base image I selected, I can commit the changes in the repo and move on with the process.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 2 - CI Integration
&lt;/h1&gt;

&lt;p&gt;I will now &lt;strong&gt;integrate Snyk with my Continuous Integration workflow&lt;/strong&gt;. I don't have any in this project yet, so I'm going to use &lt;a href="https://github.com/snyk/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a quick Google search, I found out that &lt;strong&gt;Snyk already published a GitHub action&lt;/strong&gt; I can use to scan my repository on every commit and collect the results in the Security tab of the GitHub repo.&lt;br&gt;
&lt;a href="https://github.com/snyk/actions/tree/master/docker" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3i9z77mehl8h0lzzdp8g.png" alt="snyk docker action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will then &lt;strong&gt;copy the template provided&lt;/strong&gt;, and create a new file in my repo in the &lt;code&gt;.github/workflows&lt;/code&gt; directory called &lt;code&gt;secscan.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: Container Scan
on: push
&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  snyk:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Build the Docker image
      run: docker build &lt;span class="nt"&gt;-t&lt;/span&gt; mcastellin/snyk-container-demo &lt;span class="nb"&gt;.&lt;/span&gt;
    - name: Run Snyk to check Docker image &lt;span class="k"&gt;for &lt;/span&gt;vulnerabilities
      &lt;span class="c"&gt;# Snyk can be used to break the build when it detects vulnerabilities.&lt;/span&gt;
      &lt;span class="c"&gt;# In this case we want to upload the issues to GitHub Code Scanning&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="nt"&gt;-on-error&lt;/span&gt;: &lt;span class="nb"&gt;true
      &lt;/span&gt;uses: snyk/actions/docker@master
      &lt;span class="nb"&gt;env&lt;/span&gt;:
        &lt;span class="c"&gt;# In order to use the Snyk Action you will need to have a Snyk API token.&lt;/span&gt;
        &lt;span class="c"&gt;# More details in https://github.com/snyk/actions#getting-your-snyk-token&lt;/span&gt;
        &lt;span class="c"&gt;# or you can signup for free at https://snyk.io/login&lt;/span&gt;
        SNYK_TOKEN: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.SNYK_TOKEN &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
      with:
        image: mcastellin/snyk-container-demo
        args: &lt;span class="nt"&gt;--file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Dockerfile &lt;span class="nt"&gt;--exclude-base-image-vulns&lt;/span&gt;
    - name: Upload result to GitHub Code Scanning
      uses: github/codeql-action/upload-sarif@v1
      with:
        sarif_file: snyk.sarif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have pretty much used the standard values here, except for the &lt;code&gt;args: --file=Dockerfile --exclude-base-image-vulns&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By adding the &lt;code&gt;--exclude-base-image-vulns&lt;/code&gt; parameter we are telling Snyk &lt;strong&gt;not to report vulnerabilities that are introduced by Docker base image layers&lt;/strong&gt;. This is to make sure that we are &lt;strong&gt;breaking the build only when we introduce new issues in the Dockerfile&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The reason for ignoring base image vulnerabilities is to &lt;strong&gt;avoid having too much noise in the CI scan&lt;/strong&gt;. We have already accepted the base image so we're only interested in blocking the issues we add with our customizations.&lt;/p&gt;

&lt;p&gt;Before committing our GitHub Action YAML file, we have to configure the &lt;code&gt;secret.SNYK_TOKEN&lt;/code&gt; in our registry. In the GitHub repository settings, go to &lt;em&gt;Settings &amp;gt; Secrets &amp;gt; New Secret&lt;/em&gt; and configure the value for the Snyk token:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp9j923fnvmwz92ls5cb3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp9j923fnvmwz92ls5cb3.png" alt="add new secret to github"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now push our changes and see the result of the security scan:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpgqllp1i474oz0hbowks.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpgqllp1i474oz0hbowks.png" alt="github action scan results"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 3 - Breaking the build
&lt;/h1&gt;

&lt;p&gt;After all the effort fixing vulnerabilities &lt;strong&gt;I really want to make sure nobody can introduce new ones&lt;/strong&gt;! Let's modify our Dockerfile and open a Pull Request that introduces an insecure package: &lt;code&gt;curl&lt;/code&gt;, who knew!? 🤔&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;...

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-qqy&lt;/span&gt; curl &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Found it!
&lt;/h3&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvf4qzc3ws12kr80po7hv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvf4qzc3ws12kr80po7hv.png" alt="build broken"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the &lt;strong&gt;container scan found new vulnerabilities&lt;/strong&gt;, giving us the peace of mind, that if anyone installs dodgy packages we'll be able to catch it before merging the code into the main branch! &lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4 - Analyzing the report
&lt;/h1&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbwgc9tvqx0k71qa7be1g.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbwgc9tvqx0k71qa7be1g.png" alt="detailed vulnerability report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For every issue found by Snyk you'll get a very detailed report, telling you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;what file&lt;/strong&gt; introduced the issue&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;description&lt;/strong&gt; of the vulnerability&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;remediation advice&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnkv0p03zh7x9g3cjdhrl.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnkv0p03zh7x9g3cjdhrl.png" alt="remediation advice"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;It's been a fun couple of days for me to attend to SnykCon 2020&lt;/strong&gt; and I hope by sharing my first experience with Snyk and container scanning, I have also &lt;strong&gt;encouraged you to learn how to make the most out of these tools&lt;/strong&gt; to keep your applications secure!&lt;/p&gt;

&lt;p&gt;Thanks for reading! And don't forget to follow me if you want to see more content like this!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bit.ly/3hTkyWU" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; 🎬&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/castellinmanuel" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/castellinmanuel/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>docker</category>
      <category>github</category>
    </item>
    <item>
      <title>Use Docker with Proxy Servers Tutorial</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Fri, 16 Oct 2020 17:59:11 +0000</pubDate>
      <link>https://dev.to/mcastellin/use-docker-with-proxy-servers-tutorial-10gg</link>
      <guid>https://dev.to/mcastellin/use-docker-with-proxy-servers-tutorial-10gg</guid>
      <description>&lt;p&gt;&lt;strong&gt;If you ever tried to run Docker in a corporate network&lt;/strong&gt; then you know what I'm talking about. To prevent potential intrusions, infrastructure engineers force all internet traffic to go through proxy servers, sometimes making it extremely difficult to run even the simplest thing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why should you read this article?
&lt;/h1&gt;

&lt;p&gt;With this tutorial, you'll learn everything there is to know on how to configure proxies for Docker engine and containers!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;configure proxy servers in &lt;strong&gt;Docker for Desktop&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;configure proxy servers with &lt;strong&gt;Linux &amp;amp; Systemd&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;use proxy servers with &lt;strong&gt;running containers&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started! 🚀&lt;/p&gt;

&lt;h1&gt;
  
  
  Quick refresher: what is a Proxy server?
&lt;/h1&gt;

&lt;p&gt;A proxy server is simply a server that sits in between your machine and the Internet, that can interact with the outside of your network on your behalf.&lt;/p&gt;

&lt;p&gt;The main reasons why you would want to use a Proxy are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To &lt;strong&gt;improve network performance&lt;/strong&gt; by caching internet content&lt;/li&gt;
&lt;li&gt;As an &lt;strong&gt;additional layer of security&lt;/strong&gt; by implementing additional encryption, protect against DoS attacks, blacklist dangerous sites, and much more&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;auditing and logging purposes&lt;/strong&gt;, many companies need to track &lt;em&gt;who and when&lt;/em&gt; access mission-critical systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How Docker uses proxies
&lt;/h1&gt;

&lt;p&gt;One thing that was very confusing for me at first, is that &lt;strong&gt;Docker daemon and Docker containers don't share the same proxy configuration&lt;/strong&gt;!&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl20qibhmg0bn14ewwg7v.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl20qibhmg0bn14ewwg7v.png" alt="Proxy settings for docker engine and containers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Settings for Docker engine
&lt;/h2&gt;

&lt;p&gt;Your Docker engine needs to connect to the internet to &lt;strong&gt;access image registries&lt;/strong&gt; and &lt;strong&gt;pull/push container images&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your settings are not correct you will typically see errors when trying to use &lt;code&gt;docker login&lt;/code&gt; or pulling images from DockerHub, see below for example:&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs3wmx8xs3s93fgvs00ih.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs3wmx8xs3s93fgvs00ih.png" alt="docker pull fail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting a Proxy on Docker for Mac/Windows
&lt;/h2&gt;

&lt;p&gt;If you're running Docker for Desktop this is a really simple operation. You can do this from Docker's settings &lt;code&gt;Docker &amp;gt; Preferences &amp;gt; Resources &amp;gt; Proxies&lt;/code&gt;. All you need to do is provide values for the following variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HTTP_PROXY&lt;/code&gt;: the proxy server endpoint to handle HTTP calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HTTPS_PROXY&lt;/code&gt;: the endpoint to handle HTTPS calls &lt;em&gt;(notice this doesn't have to be an https endpoint)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NO_PROXY&lt;/code&gt;: a list of hosts that Docker can reach without using the proxy (usually you'll see &lt;code&gt;localhost,127.0.0.1&lt;/code&gt; in this field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After this, you should click the &lt;em&gt;Apply &amp;amp; Restart&lt;/em&gt; button, and you'll be able to push/pull images ✅&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq1a9myv3q9gs6fbbzt19.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq1a9myv3q9gs6fbbzt19.png" alt="docker desktop proxy settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using authentication
&lt;/h3&gt;

&lt;p&gt;One question I get asked a lot is &lt;strong&gt;how to provide authentication&lt;/strong&gt; if this form does not have a &lt;em&gt;username&lt;/em&gt; and &lt;em&gt;password&lt;/em&gt; field. I am not sure why they didn't include such fields in the configuration, but you can just &lt;strong&gt;use URL authentication&lt;/strong&gt; like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

http://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@my.proxy.com:3128/


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Setting a Proxy on Linux with Systemd
&lt;/h2&gt;

&lt;p&gt;If you're working with a Linux installation, you won't have access to some nice &lt;em&gt;Preferences&lt;/em&gt; menu. In Linux, the Docker engine is &lt;strong&gt;configured as a system service with Systemd&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Let's dust off our System Administration skills! 👨🏻‍💻&lt;/p&gt;

&lt;p&gt;In most Linux distributions, Docker is configured as a service with Systemd. You can alter the service configuration by creating an &lt;strong&gt;override file&lt;/strong&gt;. Follow these simple steps:&lt;/p&gt;

&lt;p&gt;1) Edit the Docker service configuration with:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl edit docker.service


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Systemd will open (or create) the service override file with your default terminal editor.&lt;/p&gt;

&lt;p&gt;2) Add or modify the service configuration to include proxy variables. Your service file should look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[Service]
Environment=“HTTP_PROXY=http://10.0.1.60:3128”
Environment=“HTTPS_PROXY=http://10.0.1.60:3128”
Environment=“NO_PROXY=localhost,127.0.0.1”


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;3) &lt;strong&gt;Save and close&lt;/strong&gt; the file, and restart Docker with&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker.service&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Running containers with proxy settings&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you set up proxies for Docker engine, you need to understand that &lt;strong&gt;Docker will never share those settings with running containers&lt;/strong&gt;! 👎🏻&lt;/p&gt;

&lt;p&gt;If you want your containers to access the internet, you'll need to supply Proxy settings &lt;strong&gt;using environment variables&lt;/strong&gt; like this for example:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; docker run &lt;span class="se"&gt;&amp;lt;/span&amp;gt;&lt;br&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;a href="http://my.proxy.com:3128" rel="noopener noreferrer"&gt;http://my.proxy.com:3128&lt;/a&gt;"&lt;/span&gt; &lt;span class="se"&gt;&amp;lt;/span&amp;gt;&lt;br&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;a href="http://my.proxy.com:3128" rel="noopener noreferrer"&gt;http://my.proxy.com:3128&lt;/a&gt;"&lt;/span&gt; &lt;span class="se"&gt;&amp;lt;/span&amp;gt;&lt;br&gt;
    nginx sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"curl google.com"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Full Step-By-Step Tutorial&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;Take a look at my video below to see everything I described in the article in a real environment!&lt;/p&gt;

&lt;p&gt;In the video, I'll also explain how you can configure Docker to &lt;strong&gt;use proxy configuration for containers by default&lt;/strong&gt;? This way you won't have to pass &lt;code&gt;http_proxy&lt;/code&gt; and &lt;code&gt;https_proxy&lt;/code&gt; variables every time.&lt;/p&gt;

&lt;p&gt;Productivity? Yes, please! 🚀&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cmIc-3NKiL8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Don't forget to follow me&lt;/strong&gt; for more content like this!
&lt;/h3&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>linux</category>
    </item>
    <item>
      <title>Hacktoberfest - Ideas for Contributing as a Beginner</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Thu, 01 Oct 2020 22:16:45 +0000</pubDate>
      <link>https://dev.to/mcastellin/hacktoberfest-ideas-for-contributing-as-a-beginner-4k3b</link>
      <guid>https://dev.to/mcastellin/hacktoberfest-ideas-for-contributing-as-a-beginner-4k3b</guid>
      <description>&lt;p&gt;First day into &lt;strong&gt;Hacktoberfest&lt;/strong&gt;! Yay! And I'm already freaking out about it! 🤪&lt;/p&gt;

&lt;p&gt;It was fun publicly committing to make four OpenSource contributions in the next month, &lt;strong&gt;but then reality kicked in&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For beginners, it's really hard to find issues they can work on&lt;/strong&gt;. Especially if it's their first time trying to get into OpenSource. Thirty days is not a long time for&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;finding a project that picks your interest&lt;/li&gt;
&lt;li&gt;learning the codebase&lt;/li&gt;
&lt;li&gt;make contributions&lt;/li&gt;
&lt;li&gt;have them approved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As someone that never made significant contributions before, I feel I have to think outside the box if I want this to be a good experience and become part of my life as a programmer even after the event.&lt;/p&gt;

&lt;h3&gt;
  
  
  My personal dilemma with Hacktoberfest
&lt;/h3&gt;

&lt;p&gt;As a Software Engineer, I want to learn as much as I can about Containers and DevOps, so the ideal project for me would be something related to &lt;strong&gt;Docker&lt;/strong&gt; or &lt;strong&gt;Kubernetes&lt;/strong&gt; or any other related software like &lt;strong&gt;Prometheus&lt;/strong&gt; or &lt;strong&gt;Helm&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Problem is, I am not a &lt;em&gt;Go&lt;/em&gt; developer, and the entire ecosystem is written in Go! So even though I'm a hardcore user of these tools, I cannot possibly think that I'll be able to make &lt;strong&gt;four significant code contributions in one month&lt;/strong&gt;. 🤯&lt;/p&gt;

&lt;h1&gt;
  
  
  Creative Ways to Contribute
&lt;/h1&gt;

&lt;p&gt;Of course, the logical way is contributing to code, although it's not easy to start with. &lt;strong&gt;It takes skills that cannot be acquired in a few days&lt;/strong&gt;, and you don't want to be spamming maintainers with Pull Requests that are half baked &lt;em&gt;(always respect other people's time, that's my motto!)&lt;/em&gt;. So I can think of these additional ways beginners (like myself) can contribute successfully. Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation &amp;amp; Knowledge Base
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;There's always a need for documentation&lt;/strong&gt;. If you like writing and you're detailed oriented, this will be a great way for you to contribute.&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flfy5karwzfz247vrf47j.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flfy5karwzfz247vrf47j.png" alt="Use documentation labels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you search for issues try to click the filter option and search for labels that contain the word &lt;strong&gt;documentation&lt;/strong&gt; or &lt;strong&gt;docs&lt;/strong&gt; and see if there's anything urgent that needs attention. Maintainers will welcome a good piece of documentation any day!&lt;/p&gt;

&lt;h3&gt;
  
  
  READ, READ, then READ MORE!
&lt;/h3&gt;

&lt;p&gt;Have documentation for breakfast, lunch and dinner. Pick a topic you know very well, and go through the documentation pages for that topic. I can guarantee you'll find something you can improve using the knowledge you acquired with years of hard work.&lt;/p&gt;

&lt;h3&gt;
  
  
  README.md
&lt;/h3&gt;

&lt;p&gt;How was your experience when starting out with the project? Did you find everything you needed in the &lt;code&gt;README.md&lt;/code&gt; file or you had to figure things out by yourself? &lt;/p&gt;

&lt;p&gt;If the latter is true, can you improve the README file for other aspiring contributors?&lt;/p&gt;

&lt;h2&gt;
  
  
  Graphic Design
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every awesome OpenSource project needs graphics&lt;/strong&gt; to use in their:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation pages&lt;/li&gt;
&lt;li&gt;README files&lt;/li&gt;
&lt;li&gt;Websites&lt;/li&gt;
&lt;li&gt;T-shirts&lt;/li&gt;
&lt;li&gt;Stickers&lt;/li&gt;
&lt;li&gt;the list goes on... &lt;/li&gt;
&lt;/ul&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fixmc9gydhj5yvxevklrd.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fixmc9gydhj5yvxevklrd.jpg" alt="Github oops page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your passion is creating graphic elements, &lt;em&gt;reach out to the project maintainers&lt;/em&gt; and ask them if they need &lt;strong&gt;new icons&lt;/strong&gt; or maybe &lt;strong&gt;design a funny 404 or 500 page&lt;/strong&gt; (it is always nice to laugh with &lt;em&gt;Internal Server Error&lt;/em&gt; pages like the one above 😛). &lt;/p&gt;

&lt;h2&gt;
  
  
  Translate
&lt;/h2&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgo5f5h5sogghmbhq5rod.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgo5f5h5sogghmbhq5rod.png" alt="google translate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone is special, yes, you too! Just because you're alive you must be fluent in at least one language. Use your gift! Search for &lt;strong&gt;translation issues&lt;/strong&gt;, &lt;strong&gt;create content in your mother tongue&lt;/strong&gt; to help the project expand its reach and get even more people interested in the mission!&lt;/p&gt;

&lt;h2&gt;
  
  
  Educate
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Who doesn't love a good tutorial?&lt;/strong&gt; Do you love teaching others how to do things? This can be the value you bring to the project.&lt;/p&gt;

&lt;p&gt;Record a video to show &lt;strong&gt;how you installed the software&lt;/strong&gt; in a particular operating system or &lt;strong&gt;showcase one of the hottest features&lt;/strong&gt; to encourage people to "star" ⭐️ the project. These videos can then be embedded in the &lt;code&gt;README.md&lt;/code&gt; with Markdown as I did in one of my repositories&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;![K8s Autoscaling&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/media/K8s_Autoscaling.gif&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;](https://raw.githubusercontent.com/mcastellin/udacity-operationalize-microservice/master/media/K8s_Autoscaling.mp4)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Some projects have example repositories!
&lt;/h3&gt;

&lt;p&gt;You might find that the project you're interested in has a separate repo on GitHub to store &lt;strong&gt;configuration examples&lt;/strong&gt; or &lt;strong&gt;templates&lt;/strong&gt; to help people get started. See for example &lt;strong&gt;&lt;a href="https://github.com/helm/charts" rel="noopener noreferrer"&gt;Helm Charts&lt;/a&gt; or &lt;a href="https://github.com/awslabs/aws-cloudformation-templates" rel="noopener noreferrer"&gt;AWS CloudFormation Templates&lt;/a&gt;&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;Do you have work experience with the technology? Look back at your past projects, see if there's anything reusable you can share with the world! (It's a good idea to first check with your employer if you're allowed to do so 😅)&lt;/p&gt;

&lt;h2&gt;
  
  
  Organize Notes
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Interest Groups&lt;/em&gt; are most likely organising &lt;em&gt;weekly meetings&lt;/em&gt; to discuss new bugs, collect ideas, plan future meetings and so on. &lt;/p&gt;

&lt;p&gt;You can actively participate in those meetings and &lt;strong&gt;offer your services to summarise the points discussed and distribute meeting's minutes&lt;/strong&gt; via email, IM or even include them in the repo's Wiki pages! &lt;/p&gt;

&lt;h2&gt;
  
  
  Test &amp;amp; Bug Report
&lt;/h2&gt;

&lt;p&gt;Developers can't test features with every existing operating system or mobile phone. Keep a close watch on new feature releases or bug fixes and be eager to test them yourself. Then reach out to developers and provide your feedback, if something is not working as planned you can raise new issues. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you have to create a new issue, go the extra mile and include plenty of information to reproduce the bug&lt;/strong&gt;, be proactive and genuinely helpful! Help assess other people's tickets, maybe no development is needed and they are just looking for a helping hand.&lt;/p&gt;

&lt;p&gt;Who knows, maybe with a bit of time, you'll be in charge of triaging and be the one deciding what are the priorities for the project, isn't that awesome? 😎&lt;/p&gt;

&lt;h1&gt;
  
  
  In conclusion...
&lt;/h1&gt;

&lt;p&gt;...&lt;strong&gt;if you are feeling stuck in your OpenSource journey&lt;/strong&gt;, I hope this article has thrown some fuel to the fire 🔥 I know it worked for me while I was thinking about it and I'm going to start tomorrow with a different approach and even more excited than today! &lt;/p&gt;

&lt;h3&gt;
  
  
  Best of luck Developers!
&lt;/h3&gt;

&lt;p&gt;Thanks for reading! And don't forget to follow me if you want to see more content like this!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bit.ly/3hTkyWU" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; 🎬&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/castellinmanuel" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/castellinmanuel/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>beginners</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Hands-On with VSCode &amp; "Dev Containers"</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Wed, 30 Sep 2020 20:10:51 +0000</pubDate>
      <link>https://dev.to/mcastellin/hands-on-with-vscode-dev-containers-33bf</link>
      <guid>https://dev.to/mcastellin/hands-on-with-vscode-dev-containers-33bf</guid>
      <description>&lt;p&gt;Today I wanted to give &lt;strong&gt;Visual Studio Code&lt;/strong&gt; a try for the first time. Even though I still haven't found my way around it, I discovered an extension that could really be a game-changer for my workflow! 🧨 Thought to share it with you.&lt;/p&gt;

&lt;h1&gt;
  
  
  The "Remote - Containers" Extension
&lt;/h1&gt;

&lt;p&gt;In simple terms, this extension allows you to &lt;strong&gt;use a Docker container as your development environment&lt;/strong&gt;. 🤯&lt;/p&gt;

&lt;p&gt;Everything will be in it: your code, SDKs, dependencies, OS packages.. everything!&lt;/p&gt;

&lt;p&gt;I've been looking forward to something like this for a long time, and I have to say, this VSCode extension is very well thought out.&lt;/p&gt;

&lt;h3&gt;
  
  
  There are several advantages of using "dev containers"...
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility&lt;/strong&gt;: your code runs in the exact same environment from your development machine all the way to production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation &amp;amp; Speed&lt;/strong&gt;: the creation of a new dev environment is fully automated. You can restore a broken environment (or onboard a new developer) in seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PR Review&lt;/strong&gt;: you can check out the code from a PR in a new, isolated container without messing with your work&lt;/li&gt;
&lt;li&gt;It's &lt;strong&gt;CLEAN&lt;/strong&gt;! I have tons of small projects on my laptop that I can't even find anymore. With dev containers I could: checkout a project -&amp;gt; build a dev container -&amp;gt; develop and commit my changes -&amp;gt; destroy it immediately&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  How I Created My First Dev Container
&lt;/h1&gt;

&lt;p&gt;I'm now going to show you step by step how I created my first "dev container" today.&lt;/p&gt;

&lt;p&gt;I grabbed one of the projects I'll be collaborating with this Hacktoberfest. It's a Django application, so this will require our development environment to run with Python3.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;install the "Remote - Containers" extension&lt;/strong&gt; from the VSCode marketplace&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzq4yanxehzhefc7m9gkk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzq4yanxehzhefc7m9gkk.png" alt="Install new extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second, press &lt;code&gt;F1&lt;/code&gt; to open VSCode menu and search for &lt;strong&gt;"Add Development Container Configuration File"&lt;/strong&gt;.&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flaqtnctxixc4q7liz55e.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flaqtnctxixc4q7liz55e.png" alt="Add development container configuration file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you need to tell VSCode &lt;strong&gt;how you would like to create the configuration file&lt;/strong&gt;. VSCode provides predefined configuration files for the most popular languages so I found one for Python3 very easily 😊&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgh7kc2ux40tmi0dkz8v1.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgh7kc2ux40tmi0dkz8v1.png" alt="Use predefined configuration file"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rwbqmb8hh2lv08f4sob.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rwbqmb8hh2lv08f4sob.png" alt="Using python3 configuration for this project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll then be asked to choose the Python minor version to use, and if you want to install NodeJS in the container (not sure why 🤔, but I don't care at this point).&lt;/p&gt;

&lt;p&gt;VSCode should have created a new folder for you called &lt;code&gt;.devcontainer&lt;/code&gt; and generated two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;Dockerfile&lt;/code&gt;: which is the container definition for your new dev environment&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;devcontainer.json&lt;/code&gt; file: a configuration file you can use to further customize your development container build process&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Customize the &lt;code&gt;.devcontainer/Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We first look at the Dockerfile and it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/python-3/.devcontainer/base.Dockerfile&lt;/span&gt;

&lt;span class="c"&gt;# [Choice] Python version: 3, 3.8, 3.7, 3.6&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; VARIANT="3"&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}&lt;/span&gt;

&lt;span class="c"&gt;# [Option] Install Node.js&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; INSTALL_NODE="true"&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; NODE_VERSION="lts/*"&lt;/span&gt;
&lt;span class="k"&gt;RUN if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INSTALL_NODE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;su vscode &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"source /usr/local/share/nvm/nvm.sh &amp;amp;&amp;amp; nvm install &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NODE_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 2&amp;gt;&amp;amp;1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.&lt;/span&gt;
&lt;span class="c"&gt;# COPY requirements.txt /tmp/pip-tmp/&lt;/span&gt;
&lt;span class="c"&gt;# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \&lt;/span&gt;
&lt;span class="c"&gt;#    &amp;amp;&amp;amp; rm -rf /tmp/pip-tmp&lt;/span&gt;

&lt;span class="c"&gt;# [Optional] Uncomment this section to install additional OS packages.&lt;/span&gt;
&lt;span class="c"&gt;# RUN apt-get update &amp;amp;&amp;amp; export DEBIAN_FRONTEND=noninteractive \&lt;/span&gt;
&lt;span class="c"&gt;#     &amp;amp;&amp;amp; apt-get -y install --no-install-recommends &amp;lt;your-package-list-here&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# [Optional] Uncomment this line to install global node packages.&lt;/span&gt;
&lt;span class="c"&gt;# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh &amp;amp;&amp;amp; npm install -g &amp;lt;your-package-here&amp;gt;" 2&amp;gt;&amp;amp;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we want to do here, is &lt;strong&gt;making sure this container image has everything we need to run our project&lt;/strong&gt;. In this case, I need to install the required Pip packages listed in the &lt;code&gt;requirements.txt&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;The generated Dockerfile is already suggesting how to do it, &lt;em&gt;I simply have to uncomment a few lines&lt;/em&gt;. This is going to be my final Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# [Choice] Python version: 3, 3.8, 3.7, 3.6&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; VARIANT="3"&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}&lt;/span&gt;

&lt;span class="c"&gt;# [Option] Install Node.js&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; INSTALL_NODE="true"&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; NODE_VERSION="lts/*"&lt;/span&gt;
&lt;span class="k"&gt;RUN if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INSTALL_NODE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;su vscode &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"source /usr/local/share/nvm/nvm.sh &amp;amp;&amp;amp; nvm install &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NODE_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 2&amp;gt;&amp;amp;1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt /tmp/pip-tmp/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip3 &lt;span class="nt"&gt;--disable-pip-version-check&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/pip-tmp/requirements.txt &lt;span class="se"&gt;\
&lt;/span&gt;   &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /tmp/pip-tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure &lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The second file generated by VSCode is &lt;code&gt;devcontainer.json&lt;/code&gt;. This contains additional information for VSCode to create our development container. Here is how I set it up.&lt;/p&gt;

&lt;p&gt;The first section is defining how I want to build my container. I left everything with its default values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python 3"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dockerfile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'VARIANT'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pick&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.8&lt;/span&gt;&lt;span class="w"&gt; 
            &lt;/span&gt;&lt;span class="nl"&gt;"VARIANT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Options&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"INSTALL_NODE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"NODE_VERSION"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lts/*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since my Django application is going to run at &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt;, &lt;strong&gt;I need to forward port 8000 from the host machine into the container&lt;/strong&gt;, so I uncommented and edited the line below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'forwardPorts'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;available&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;locally.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forwardPorts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;I suggest you take the time to read through the file to find out about all the available options&lt;/em&gt;, but here is what mine looks like after the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;details,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://aka.ms/devcontainer.json.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;options,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;README&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;at:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://github.com/microsoft/vscode-dev-containers/tree/v&lt;/span&gt;&lt;span class="mf"&gt;0.140&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;/containers/python&lt;/span&gt;&lt;span class="mi"&gt;-3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python 3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dockerfile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'VARIANT'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pick&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.8&lt;/span&gt;&lt;span class="w"&gt; 
            &lt;/span&gt;&lt;span class="nl"&gt;"VARIANT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Options&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"INSTALL_NODE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"NODE_VERSION"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lts/*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*default*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specific&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;settings.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;values&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;create.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"terminal.integrated.shell.linux"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.pythonPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bin/python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.pylintEnabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.autopep8Path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/autopep8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.blackPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.formatting.yapfPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/yapf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.banditPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/bandit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.flake8Path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/flake8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.mypyPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/mypy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.pycodestylePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/pycodestyle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.pydocstylePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/pydocstyle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"python.linting.pylintPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/py-utils/bin/pylint"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IDs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;extensions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;want&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;installed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;when&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;created.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ms-python.python"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'forwardPorts'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;available&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;locally.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forwardPorts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'postCreateCommand'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;created.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"postCreateCommand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pip3 install --user -r requirements.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Uncomment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;non-root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;user.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;See&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://aka.ms/vscode-remote/containers/non-root.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"remoteUser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vscode"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Opening The Project as a Dev Container
&lt;/h1&gt;

&lt;p&gt;Now that everything is ready, we press &lt;code&gt;F1&lt;/code&gt; again and search for the &lt;strong&gt;"Reopen in Container"&lt;/strong&gt; option. &lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2bkant49m5zo441ouff.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2bkant49m5zo441ouff.png" alt="Reopen in container"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VSCode will now create a new development container from the &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;devcontainer.json&lt;/code&gt; you created.&lt;/p&gt;

&lt;p&gt;Project files in your workspace are now synchronized with the container and VSCode will edit them directly in it.&lt;/p&gt;

&lt;p&gt;You'll notice the green strip at the bottom left of the screen indicating VSCode is not attached to our &lt;strong&gt;Python 3&lt;/strong&gt; dev container.&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwcnk4quh4mbb7quorg6j.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwcnk4quh4mbb7quorg6j.png" alt="Project with dev container view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to test our brand new environment, let's run the application with &lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5vj4a4ju5vhqwufdbjbt.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5vj4a4ju5vhqwufdbjbt.png" alt="Run Django application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yay! The application is now running on port &lt;code&gt;8000&lt;/code&gt; and forwarded correctly through &lt;code&gt;localhost&lt;/code&gt;! &lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxwshvont30dud09l104d.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxwshvont30dud09l104d.png" alt="Browser view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  This was my experience with Dev Containers today...
&lt;/h3&gt;

&lt;p&gt;I'm impressed with this VSCode extension so far and I'm looking forward to learning more about it by using it every day. &lt;/p&gt;

&lt;p&gt;Hope this intro will inspire someone else to get started with Dev Containers in VSCode.&lt;/p&gt;

&lt;p&gt;Thank you for reading through the end! And don't forget to follow me if you want to see more content like this!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bit.ly/3hTkyWU" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; 🎬&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/castellinmanuel" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/castellinmanuel/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vscode</category>
      <category>docker</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My Top 3 Uses for "Docker Info"</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Tue, 29 Sep 2020 07:27:53 +0000</pubDate>
      <link>https://dev.to/mcastellin/my-top-3-uses-for-docker-info-3bm8</link>
      <guid>https://dev.to/mcastellin/my-top-3-uses-for-docker-info-3bm8</guid>
      <description>&lt;p&gt;The very first day I started using Docker I used &lt;code&gt;docker info&lt;/code&gt; to verify the server was installed correctly on my Mac, &lt;strong&gt;and never used it again!&lt;/strong&gt; 😅&lt;/p&gt;

&lt;p&gt;But sometimes it's good to have this simple command in your toolbox to get information quickly. Here are my top 3 uses for &lt;code&gt;docker info&lt;/code&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. To verify "if" and "which" docker engine is running
&lt;/h3&gt;

&lt;p&gt;It's obvious, I know, but &lt;code&gt;docker info&lt;/code&gt; can tell you in the simplest way &lt;strong&gt;that the Docker daemon is alive and kicking&lt;/strong&gt; and that its API is responding correctly.&lt;/p&gt;

&lt;p&gt;It's also a quick way to check &lt;strong&gt;what Docker version you're running on&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker info | &lt;span class="nb"&gt;head
&lt;/span&gt;Client:
 Debug Mode: &lt;span class="nb"&gt;false

&lt;/span&gt;Server:
 Containers: 29
  Running: 22
  Paused: 0
  Stopped: 7
 Images: 58
 Server Version: 19.03.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. System resources limit: CPU &amp;amp; Memory
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Are your containers running slowly or not starting at all?&lt;/em&gt; Check &lt;strong&gt;if your Docker daemon is running with CPU or Memory limits!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; CPU &lt;span class="nt"&gt;-e&lt;/span&gt; Memory
 CPUs: 2
 Total Memory: 1.945GiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Check engine's proxy settings
&lt;/h3&gt;

&lt;p&gt;If you run Docker in a corporate network, is very common that you need to connect to the internet via a proxy server. If you get connection timeouts it's likely that you don't have the right settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; Proxy
 HTTP Proxy: http://proxy.mycompany.com:3128
 HTTPS Proxy: http://proxy.mycompany.com:3128
 No Proxy: localhost,127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Did you know...
&lt;/h2&gt;

&lt;p&gt;you can print the full list of information in JSON format with this command?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Using "| jq" to prettify the json output, though not mandatory&lt;/span&gt;
❯ docker info &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'{{json .}}'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Do you use &lt;code&gt;docker info&lt;/code&gt; often?
&lt;/h3&gt;

&lt;p&gt;Tell me how in the comments!&lt;/p&gt;

&lt;p&gt;Don't forget to follow me if you want to see more content like this!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bit.ly/3hTkyWU"&gt;YouTube&lt;/a&gt; 🎬&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/castellinmanuel"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/castellinmanuel/"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>docker</category>
      <category>discuss</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>What is the coolest automation you created with "Crontab"?</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Fri, 25 Sep 2020 07:50:35 +0000</pubDate>
      <link>https://dev.to/mcastellin/what-is-the-coolest-automation-you-created-with-crontab-2b92</link>
      <guid>https://dev.to/mcastellin/what-is-the-coolest-automation-you-created-with-crontab-2b92</guid>
      <description>&lt;h3&gt;
  
  
  Calling all Linux enthusiasts...
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;crontab&lt;/strong&gt; is such a simple tool, but people always find creative ways to create 🔥 awesome 🔥 things with simple tools&lt;/p&gt;

&lt;p&gt;Sending mails, running programs, cleaning up files, restore connections, there's a lot you can do by scheduling a shell script&lt;/p&gt;

&lt;h3&gt;
  
  
  Mine is not that awesome really...
&lt;/h3&gt;

&lt;p&gt;...but it saved me a lot of time over the years. I have a scheduled shell script that cleans up my stale Docker containers and volumes every day. This way my laptop is always tidy and I don't have to hunt disk space hogs 😎 cool enough for me!&lt;/p&gt;

&lt;h3&gt;
  
  
  What's yours?
&lt;/h3&gt;

</description>
      <category>linux</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>ENTRYPOINT vs. CMD: The Dockerfile Dilemma</title>
      <dc:creator>Manuel Castellin</dc:creator>
      <pubDate>Thu, 24 Sep 2020 13:25:05 +0000</pubDate>
      <link>https://dev.to/mcastellin/entrypoint-vs-cmd-the-dockerfile-dilemma-gn4</link>
      <guid>https://dev.to/mcastellin/entrypoint-vs-cmd-the-dockerfile-dilemma-gn4</guid>
      <description>&lt;p&gt;Since I started using Docker ages ago, I occasionally come across blog posts or videos telling in details how the two are different, but failing to explain how and when to use them&lt;/p&gt;

&lt;h3&gt;
  
  
  With enough experience...
&lt;/h3&gt;

&lt;p&gt;you quickly realise that each instruction helps in different situations.&lt;/p&gt;

&lt;h3&gt;
  
  
  The best use for ENTRYPOINT is...
&lt;/h3&gt;

&lt;p&gt;to set the image's main command. Are you running the image as though it was a command? Then &lt;strong&gt;ENTRYPOINT&lt;/strong&gt; is the right choice. In addition to that, you can use &lt;strong&gt;CMD&lt;/strong&gt; to provide additional command line arguments.&lt;/p&gt;

&lt;p&gt;For example: you can package the &lt;code&gt;dig&lt;/code&gt; command to run DNS queries with this &lt;strong&gt;Dockerfile&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ubuntu:18.04

RUN apt-get update &amp;amp;&amp;amp;\
        apt-get install -qqy --no-install-recommends dnsutils

ENTRYPOINT ["dig"]

CMD ["--help"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I have provided &lt;code&gt;--help&lt;/code&gt; as default command line parameter for the container, this way, if none is provided, we the container displays the help page. (Because you have to love your users, don't you? 🙂)&lt;/p&gt;

&lt;p&gt;If you now build and tag your image as &lt;code&gt;dig:latest&lt;/code&gt;, you can run DNS queries with ease from any operating system!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# On your Windows or MacOs

❯ docker run dig google.com

; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.11.3-1ubuntu1.13-Ubuntu &amp;lt;&amp;lt;&amp;gt;&amp;gt; google.com
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 7619
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.com.            IN  A

;; ANSWER SECTION:
google.com.     377 IN  A   172.217.23.142

;; Query time: 55 msec
;; SERVER: 192.168.65.1#53(192.168.65.1)
;; WHEN: Thu Sep 24 12:51:14 UTC 2020
;; MSG SIZE  rcvd: 44
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWESOME! 🔥&lt;/p&gt;

&lt;h3&gt;
  
  
  Forget about ENTRYPOINT...
&lt;/h3&gt;

&lt;p&gt;when your container's users are not already familiar with how the ENTRYPOINT works! It's easy to get fancy by adding magic tricks at container startup, but avoid hiding nasty logic at all costs!&lt;/p&gt;

&lt;h3&gt;
  
  
  Use CMD for...
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;everything else!&lt;/strong&gt; When in doubt, I always use the plain and simple &lt;strong&gt;CMD&lt;/strong&gt;. And if you're not sure what your container should do by default, just give your users a Shell to work with, as simple as that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CMD ["bash"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What do you think?
&lt;/h3&gt;

&lt;p&gt;I'm curious to know how you use ENTRYPOINT and CMD in your Dockerfiles!&lt;/p&gt;

&lt;p&gt;Thanks for reading! And don't forget to follow me if you want to see more content like this!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bit.ly/3hTkyWU"&gt;YouTube&lt;/a&gt; 🎬&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/castellinmanuel"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/castellinmanuel/"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
