<?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: Reishi Mitani</title>
    <description>The latest articles on DEV Community by Reishi Mitani (@greenteabiscuit).</description>
    <link>https://dev.to/greenteabiscuit</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%2F435973%2F88d5c7a2-bafe-4e7f-9079-b15a20c64f50.jpeg</url>
      <title>DEV Community: Reishi Mitani</title>
      <link>https://dev.to/greenteabiscuit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/greenteabiscuit"/>
    <language>en</language>
    <item>
      <title>Getting started with wolfssl</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Fri, 23 Sep 2022 09:09:05 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/getting-started-with-wolfssl-5dck</link>
      <guid>https://dev.to/greenteabiscuit/getting-started-with-wolfssl-5dck</guid>
      <description>&lt;p&gt;First, clone the repository. This is going to take some time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/wolfssl/wolfssl
Cloning into 'wolfssl'...

// will take a few minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the directory and run &lt;code&gt;autogen&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd autogen.sh
$ sh autogen.sh
glibtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
glibtoolize: copying file 'build-aux/ltmain.sh'
glibtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
glibtoolize: copying file 'm4/libtool.m4'
glibtoolize: copying file 'm4/ltoptions.m4'
glibtoolize: copying file 'm4/ltsugar.m4'
glibtoolize: copying file 'm4/ltversion.m4'
glibtoolize: copying file 'm4/lt~obsolete.m4'
configure.ac:22: installing 'build-aux/compile'
configure.ac:24: installing 'build-aux/config.guess'
configure.ac:24: installing 'build-aux/config.sub'
configure.ac:28: installing 'build-aux/install-sh'
configure.ac:28: installing 'build-aux/missing'
Makefile.am: installing 'build-aux/depcomp'
parallel-tests: installing 'build-aux/test-driver'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After finishing, run the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
....
   * IoT-Safe:                   no
   * IoT-Safe HWRNG:             no
   * NXP SE050:                  no
   * PSA:                        no

---

$ make check
/Applications/Xcode.app/Contents/Developer/usr/bin/make -j17  check-recursive
make[2]: warning: -jN forced in submake: disabling jobserver mode.
  CC       wolfcrypt/src/src_libwolfssl_la-hmac.lo
  CC       wolfcrypt/benchmark/benchmark.o
....
/Applications/Xcode.app/Contents/Developer/usr/bin/make -j17  check-TESTS
make[3]: warning: -jN forced in submake: disabling jobserver mode.
make[4]: warning: -jN forced in submake: disabling jobserver mode.
SKIP: scripts/openssl.test
SKIP: scripts/external.test
PASS: testsuite/testsuite.test
PASS: scripts/resume.test
PASS: scripts/google.test
PASS: scripts/tls13.test
PASS: scripts/unit.test
============================================================================
Testsuite summary for wolfssl 5.5.0
============================================================================
# TOTAL: 7
# PASS:  5
# SKIP:  2
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0
============================================================================
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, install the library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo make install
Password:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can try out sample samples as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In one window
$ ./examples/server/server

// In another
./examples/client/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using software like Wireshark, we can see that the server and the client are talking to each other using encrypted data.&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%2Fuploads%2Farticles%2Fx3xav05cpon7k5392y8s.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%2Fuploads%2Farticles%2Fx3xav05cpon7k5392y8s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>Transmitting a sine wave from Matlab to Pluto</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Thu, 03 Feb 2022 06:16:38 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/transmitting-a-sine-wave-from-matlab-to-pluto-gab</link>
      <guid>https://dev.to/greenteabiscuit/transmitting-a-sine-wave-from-matlab-to-pluto-gab</guid>
      <description>&lt;p&gt;I recently had to configure my Matlab code to send a sine wave to Adalm Pluto. I set the gain to -1 and the frequency to 2.4 GHz. I am pausing the code so that I can check the pulse on my spectrum analyzer.&lt;/p&gt;

&lt;p&gt;Below is the code that I used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deviceNameSDR = 'Pluto'; % Set SDR Device
radio = sdrdev(deviceNameSDR);           % Create SDR device object

txGain = -1;

% sdrTransmitter = sdrtx(deviceNameSDR); % Transmitter properties
% sdrTransmitter.RadioID = 'usb:0';

tx = sdrtx(deviceNameSDR);
tx.RadioID = 'usb:0';
tx.CenterFrequency = 2.415e9;
tx.BasebandSampleRate = fs;
tx.Gain = 0;

fs = 2e6;
sw = dsp.SineWave;
sw.Amplitude = 100;
sw.Frequency = 2.432e9;
sw.ComplexOutput = true;
sw.SampleRate = fs;
sw.SamplesPerFrame = 20000; 
txWaveform = sw();

transmitRepeat(tx,txWaveform);

pause(60)

release(tx);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pulse looks like below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ODbvA7I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru316exwomnijdiaex6s.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ODbvA7I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru316exwomnijdiaex6s.jpeg" alt="Image description" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I connected Pluto to my PC and my spectrum analyzer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N6G8N3XG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lpeo0f4gt1pok4h3fcw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N6G8N3XG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lpeo0f4gt1pok4h3fcw.jpeg" alt="Image description" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>matlab</category>
    </item>
    <item>
      <title>Creating a simple local server from scratch using node and express</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Sun, 15 Nov 2020 14:24:38 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/creating-a-simple-local-server-from-scratch-using-node-and-express-4hjf</link>
      <guid>https://dev.to/greenteabiscuit/creating-a-simple-local-server-from-scratch-using-node-and-express-4hjf</guid>
      <description>&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a local server on your machine using node.js
We will first create a simple app that shows hello world and then use express.js for routing. Finally, we will create some APIs and route them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mac OS Catalina&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create an app with a simple local server that returns Hello World
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// create your own directory
$ mkdir node-practice &amp;amp;&amp;amp; cd node-practice
// initialize your project
$ npm init -y
// create your app.js
$ touch app.js
$ vi app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit your app.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const http = require('http');
const server = http.createServer((req, res)=&amp;gt;{
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World!');
})
server.listen(8080);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the command below, and access &lt;code&gt;localhost:8080&lt;/code&gt;. You should see Hello World appear in the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--56xhBzIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d1jcu7nmr581jdjo9f7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--56xhBzIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d1jcu7nmr581jdjo9f7f.png" alt="Alt Text" width="446" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing express
&lt;/h2&gt;

&lt;p&gt;We will install express.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install express -save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create our public folder
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir public &amp;amp;&amp;amp; cd public
$ touch index.html
$ mkdir css img js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your folders should look like this now, excluding the node_modules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree -I node_modules
.
├── app.js
├── package-lock.json
├── package.json
└── public
    ├── css
    ├── img
    ├── index.html
    └── js

4 directories, 4 files

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

&lt;/div&gt;



&lt;p&gt;We will create the following files inside each of our files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node-practice/public$ cd css &amp;amp;&amp;amp; touch sample.css
node-practice/public$ cd js &amp;amp;&amp;amp; touch sample.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will have a sample photo inside my img folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tUnCdmg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n01uxbtwogu73mv299bt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tUnCdmg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n01uxbtwogu73mv299bt.jpeg" alt="Alt Text" width="500" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now your folders should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree -I node_modules
.
├── app.js
├── package-lock.json
├── package.json
└── public
    ├── css
    │   └── sample.css
    ├── img
    │   └── sample.jpeg
    ├── index.html
    └── js
        └── sample.js

4 directories, 7 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For our index.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width,initial-scale=1"&amp;gt;
    &amp;lt;title&amp;gt;TEST&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="/css/sample.css"&amp;gt;
  &amp;lt;/head&amp;gt;

  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
    &amp;lt;p id="hoge"&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;img src="/img/sample.jpeg"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src="/js/sample.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For our sample.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* /public/js/sample.js */
{
  const el = document.getElementById('hoge');
  el.innerText = 'HAHAHAHAHAHAHA!!!!';
}

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

&lt;/div&gt;



&lt;p&gt;For our sample.css:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* /public/css/sample.css */
h1 {
  font-size: 1.5rem;
  color: #0000ff;
}
img {
  max-width: 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Edit our app.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const path = require('path');

app.listen(8080, () =&amp;gt; {
  console.log('Running at Port 8080...');
});

app.use(express.static(path.join(__dirname, 'public')));

app.use((req, res) =&amp;gt; {
  res.sendStatus(404);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run the following, you should see the web page on &lt;code&gt;localhost:8080&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UAQ9c7fn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9dh0w3r4hvtet0v72yrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UAQ9c7fn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9dh0w3r4hvtet0v72yrx.png" alt="Alt Text" width="880" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create our APIs
&lt;/h2&gt;

&lt;p&gt;We will create our apis, by creating a folder first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// at the root directory of the project.
$ mkdir api &amp;amp;&amp;amp; cd api
$ touch data.json index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create some random data in data.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": "W0001",
  "title": "I Love Cats and Dogs",
  "price": 3000000000000
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For index.js, we export our api router.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const router = express.Router();

router.use(express.json());

router.get('/foo', (req, res) =&amp;gt; {
    res.sendFile(__dirname + '/data.json', (err) =&amp;gt; {
        if (err) {
            res.sendStatus(400);
        } else {
            console.log('completed');
        }
    });
});

router.route('/bar')
    .get((req, res) =&amp;gt; {
        res.json(req.query);
    })
    .post((req, res) =&amp;gt; {
        const nameArray = ['id', 'name', 'address'], failed = nameArray.some(v=&amp;gt;!req.body[v]);
        if (failed) {
            res.sendStatus(400);
        } else {
            res.sendStatus(200);
        }
    });

module.exports = router;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our folders should look like this now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree -I node_modules
.
├── api
│   ├── data.json
│   └── index.js
├── app.js
├── package-lock.json
├── package.json
└── public
    ├── css
    │   └── sample.css
    ├── img
    │   └── sample.jpeg
    ├── index.html
    └── js
        └── sample.js

5 directories, 9 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we will edit our app.js in our root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const path = require('path');
const api = require('./api/');

app.listen(8080, () =&amp;gt; {
    console.log('Running at port 8080...');
});

app.use('/api', api);
app.use(express.static(path.join(__dirname, 'public')));

app.use((req, res) =&amp;gt; {
    res.sendStatus(404);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we run node app.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the APIs
&lt;/h2&gt;

&lt;p&gt;Let's use &lt;a href="https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=ja"&gt;Advanced REST Client&lt;/a&gt; to see how the APIs are working.&lt;/p&gt;

&lt;p&gt;When we throw &lt;code&gt;http://localhost:8080&lt;/code&gt;, we get the following result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Iz94KFQM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/llyhoged8puwtsofmqft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Iz94KFQM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/llyhoged8puwtsofmqft.png" alt="Alt Text" width="859" height="759"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we throw &lt;code&gt;http://localhost:8080/api/foo&lt;/code&gt;, we get the &lt;code&gt;data.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F03I8u9a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kt39wopjzwwktqkdt3hs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F03I8u9a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kt39wopjzwwktqkdt3hs.png" alt="Alt Text" width="835" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we throw &lt;code&gt;http://localhost:8080/api/bar?name=johndoe&amp;amp;address=USA&amp;amp;age=17&lt;/code&gt;, we get the json from the URL values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R5muMM_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0cpftc0htzhgvlgk6gtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R5muMM_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0cpftc0htzhgvlgk6gtq.png" alt="Alt Text" width="844" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's POST some data using the &lt;code&gt;bar&lt;/code&gt; api. We can add it by editing the body parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0-TQvVd9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sdyig3s8i6w1nqv4abud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0-TQvVd9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sdyig3s8i6w1nqv4abud.png" alt="Alt Text" width="843" height="705"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can see that the APIs are working, both GET and POST!&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Set tab to 4 spaces in vim</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Wed, 11 Nov 2020 00:30:04 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/set-tab-to-4-spaces-in-vim-9p4</link>
      <guid>https://dev.to/greenteabiscuit/set-tab-to-4-spaces-in-vim-9p4</guid>
      <description>&lt;p&gt;Create or edit .vimrc in your default directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// go back to your root directory
$ cd
// create or edit .vimrc
$ vi .vimrc

// inside .vimrc, add the line below
set tabstop=4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>vim</category>
    </item>
    <item>
      <title>Downloading Ubuntu onto Mac VirtualBox</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Thu, 05 Nov 2020 06:54:14 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/downloading-ubuntu-onto-mac-virtualbox-276e</link>
      <guid>https://dev.to/greenteabiscuit/downloading-ubuntu-onto-mac-virtualbox-276e</guid>
      <description>&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Already have VirtualBox installed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Procedures
&lt;/h1&gt;

&lt;p&gt;Access the website for Ubuntu and click download: &lt;a href="https://ubuntu.com/download/desktop/thank-you?version=20.04.1&amp;amp;architecture=amd64"&gt;website for Ubuntu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--80RmeRJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7cr6muxh7zv05bucs15r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--80RmeRJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7cr6muxh7zv05bucs15r.png" alt="Alt Text" width="880" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The iso file is about 3 GBs.&lt;/p&gt;

&lt;p&gt;We will create a new VM once the file is downloaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LyyYhWUz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7bmkhhd0d51tmd3xs481.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LyyYhWUz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7bmkhhd0d51tmd3xs481.png" alt="Alt Text" width="880" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will name the VM Ubuntu-ns3, since I want to install ns3 later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZWAUaIoW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yrqqnw7v614y3vdnqtaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZWAUaIoW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yrqqnw7v614y3vdnqtaw.png" alt="Alt Text" width="880" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will allocate 1024MB of memory to the VM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6qIDv0ja--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lzbamd3ecuuagsmwb1wf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6qIDv0ja--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lzbamd3ecuuagsmwb1wf.png" alt="Alt Text" width="880" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select create virtual hard disk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xzjZoUsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlvaz839o92f43utw1j6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xzjZoUsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlvaz839o92f43utw1j6.png" alt="Alt Text" width="880" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select VDI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t_ObKmPT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tqblt3pltnd7874rkxdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t_ObKmPT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tqblt3pltnd7874rkxdp.png" alt="Alt Text" width="880" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select fixed size for storage on the hard disk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oPetynPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24y0zqybgkq6fgiiofrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oPetynPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24y0zqybgkq6fgiiofrk.png" alt="Alt Text" width="880" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I allocated 40GB for the size. The default is 10GB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h2aKvaqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l9zdv7dvxw17198zmxpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h2aKvaqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l9zdv7dvxw17198zmxpn.png" alt="Alt Text" width="880" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now once we are back on this page, we press start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BVk1AT6h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/78nqfbmmul0eishxvcbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BVk1AT6h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/78nqfbmmul0eishxvcbo.png" alt="Alt Text" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the file we previously downloaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TYvhXUCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mnj838at709obcuak7cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TYvhXUCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mnj838at709obcuak7cg.png" alt="Alt Text" width="880" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the orders below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JIqk8tpt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2oddjil7r1szwgx0xhr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JIqk8tpt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2oddjil7r1szwgx0xhr7.png" alt="Alt Text" width="880" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose English as your language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--76_3NkZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2e6ox6hy9pc85o8pgwyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--76_3NkZp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2e6ox6hy9pc85o8pgwyg.png" alt="Alt Text" width="880" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose normal installation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ezbeqwSr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/alm9c9ymhfmqem9z08oq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ezbeqwSr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/alm9c9ymhfmqem9z08oq.png" alt="Alt Text" width="880" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose erase disk and install Ubuntu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P7gKzu4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/58a2sltdr8odzf86ruyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P7gKzu4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/58a2sltdr8odzf86ruyh.png" alt="Alt Text" width="880" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;continue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VOpYHYjm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/84wg0tv427ycc78h5hyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VOpYHYjm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/84wg0tv427ycc78h5hyv.png" alt="Alt Text" width="880" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you choose your location, the following should appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NjQ-BCjM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9us75r946b7ct72ky35p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NjQ-BCjM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9us75r946b7ct72ky35p.png" alt="Alt Text" width="880" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait a few minutes while the OS is being installed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UxgVQ4ZA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7a7jg8oox2386b0t356.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UxgVQ4ZA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7a7jg8oox2386b0t356.png" alt="Alt Text" width="792" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, the welcome page will appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kOK7RiAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ingv2t53mna6pg771hrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kOK7RiAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ingv2t53mna6pg771hrz.png" alt="Alt Text" width="880" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Mini gRPC Project (2): Deploying the gRPC API on k8s</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Fri, 16 Oct 2020 02:05:28 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/mini-grpc-project-deploying-the-grpc-api-on-k8s-4h15</link>
      <guid>https://dev.to/greenteabiscuit/mini-grpc-project-deploying-the-grpc-api-on-k8s-4h15</guid>
      <description>&lt;p&gt;This is part 2 of &lt;a href="https://dev.to/greenteabiscuit/mini-grpc-project-creating-a-simple-increment-api-on-go-6cn"&gt;Mini gRPC Project (1): Creating a Simple Increment API on Go&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;MacOS Catalina&lt;/li&gt;
&lt;li&gt;Already have gopaths configured&lt;/li&gt;
&lt;li&gt;Have a GCP project of your own&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Overview of the Directory
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── README.md
├── infrastructure
│   ├── backend-deployment.yml
│   ├── backend-service.yml
│   ├── frontend-deployment.yml
│   └── frontend-service.yml
├── proto
│   ├── calc.proto
│   └── gen
│       └── calc.pb.go
└── src
    ├── backend
    │   ├── Dockerfile
    │   └── main.go
    └── frontend
        ├── Dockerfile
        └── main.go

6 directories, 11 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create Dockerfiles
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;src/frontend/Dockerfile&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Make sure to push your protos to your github account so that you can import them.&lt;br&gt;
&lt;/p&gt;

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

ENV HOME /root
ENV PATH $PATH:/usr/local/go/bin
ENV GOPATH /go 
RUN echo $GOPATH
RUN go get -u github.com/golang/protobuf/protoc-gen-go
RUN go get -u github.com/grpc-ecosystem/go-grpc-middleware/logging/zap
RUN go get -u go.uber.org/zap
RUN go get -u github.com/YOURACCOUNT/micro-prac/proto/gen
WORKDIR /go/src/micro-sample-frontend
COPY . .

RUN go build -o /usr/local/bin/micro-sample-frontend

CMD ["micro-sample-frontend"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;src/backend/Dockerfile&lt;/code&gt;
&lt;/h2&gt;



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

ENV HOME /root
ENV PATH $PATH:/usr/local/go/bin
ENV GOPATH /go 
RUN echo $GOPATH
RUN go get -u github.com/golang/protobuf/protoc-gen-go
RUN go get -u github.com/grpc-ecosystem/go-grpc-middleware/logging/zap
RUN go get -u go.uber.org/zap

# Make sure to push your protos to your github account
RUN go get -u github.com/YOURACCOUNT/micro-prac/proto/gen

WORKDIR /go/src/micro-sample-backend
COPY . .

RUN go build -o /usr/local/bin/micro-sample-backend

CMD ["micro-sample-backend"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create the Docker Images
&lt;/h1&gt;

&lt;p&gt;To build, use the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t gcr.io/$PROJECT_ID/micro-sample-frontend:v0.1 .
docker build -t gcr.io/$PROJECT_ID/micro-sample-backend:v0.1 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create GCP project
&lt;/h1&gt;

&lt;p&gt;I created a project and in my GKE created a cluster called &lt;code&gt;micro-sample&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%2Fligcopkk1qiw93pl5p74.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%2Fligcopkk1qiw93pl5p74.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my local machine, we will run the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gcloud init
Welcome! This command will take you through the configuration of gcloud.

// Choose the correct configurations for your project.
.......

$ gcloud container clusters get-credentials micro-sample --zone="asia-northeast1-a"
Fetching cluster endpoint and auth data.
kubeconfig entry generated for micro-sample.

$ kubectl config current-context
gke_$PROJECT_ID_asia-northeast1-a_micro-sample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Push the images to GCR
&lt;/h2&gt;

&lt;p&gt;We will push the built images to GCR, now the GCP project is created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push gcr.io/$PROJECT_ID/micro-sample-frontend:v0.1
docker push gcr.io/$PROJECT_ID/micro-sample-backend:v0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should be able to see your repositories in your GCR.&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%2Fhqz24dbkm5m5aoltx58e.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%2Fhqz24dbkm5m5aoltx58e.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create service yaml files.
&lt;/h1&gt;

&lt;p&gt;Make sure to replace the $PROJECT_ID with your own GCP project id. We will create a new folder named &lt;code&gt;infrastructure&lt;/code&gt; and store all the yaml files in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;infrastructure$ tree
.
├── backend-deployment.yml
├── backend-service.yml
├── frontend-deployment.yml
└── frontend-service.yml

0 directories, 4 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;infrastructure/backend-deployment.yml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: micro-sample-backend-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: micro-sample
  template:
    metadata:
      labels:
        app: micro-sample
        tier: backend
        track: stable
    spec:
      containers:
      - name: micro-sample
        image: gcr.io/$PROJECT_ID/micro-sample-backend:v0.1
        ports:
        - containerPort: 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;infrastructure/backend-service.yml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind: Service
apiVersion: v1
metadata:
  name: micro-sample-service-backend
spec:
  selector:
    app: micro-sample
    tier: backend
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;infrastructure/frontend-deployment.yml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: micro-sample-frontend-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: micro-sample
  template:
    metadata:
      labels:
        app: micro-sample
        tier: frontend
        track: stable
    spec:
      containers:
      - name: micro-sample-frontend
        image: gcr.io/$PROJECT_ID/micro-sample-frontend:v0.1
        ports:
          - containerPort: 8080
            name: http
        env:
          - name: BACKEND_SERVICE_NAME
            value: micro-sample-service-backend.default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;infrastructure/frontend-service.yml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind: Service
apiVersion: v1
metadata:
  name: micro-sample-service-frontend
spec:
  type: LoadBalancer
  selector:
    app: micro-sample
    tier: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configurations in GCP
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f frontend-service.yml
service/micro-sample-service-frontend created

$ kubectl apply -f frontend-deployment.yml
deployment.apps/micro-sample-frontend-deployment created

$ kubectl apply -f backend-service.yml
service/micro-sample-service-backend created

$ kubectl apply -f backend-deployment.yml
deployment.apps/micro-sample-backend-deployment created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Check the pods in your cluster
&lt;/h1&gt;

&lt;p&gt;In your local machine when you run &lt;code&gt;kubectl get pods&lt;/code&gt;, you should be able to see that all the pods are up and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pods
NAME                                                READY   STATUS    RESTARTS   AGE
micro-sample-backend-deployment-854c888c95-46dp5    1/1     Running   0          98s
micro-sample-backend-deployment-854c888c95-l4g48    1/1     Running   0          98s
micro-sample-frontend-deployment-5cf875f7c9-2htft   1/1     Running   0          3m33s
micro-sample-frontend-deployment-5cf875f7c9-g4kpn   1/1     Running   0          3m33s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the external IP of your cluster and run &lt;code&gt;curl&lt;/code&gt;. You should be able to get the results from the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get svc
NAME                            TYPE           CLUSTER-IP   EXTERNAL-IP    PORT(S)        AGE
kubernetes                      ClusterIP      10.4.0.1     &amp;lt;none&amp;gt;         443/TCP        15m
micro-sample-service-backend    ClusterIP      10.4.8.222   &amp;lt;none&amp;gt;         8000/TCP       51s
micro-sample-service-frontend   LoadBalancer   10.4.15.80   EXTERNAL_IP   80:31017/TCP   7m44s

$ curl "http://EXTERNAL_IP/increment?val=1"
{"val":2}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Cleaning Up
&lt;/h1&gt;

&lt;p&gt;We will delete both the frontend and backend services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete svc micro-sample-service-frontend
service "micro-sample-service-frontend" deleted

//check if they are deleted
$ kubectl get services
NAME                           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes                     ClusterIP   10.4.0.1     &amp;lt;none&amp;gt;        443/TCP    14h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we will delete the cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gcloud container clusters delete micro-sample
The following clusters will be deleted.
 - [micro-sample] in [asia-northeast1-a]

Do you want to continue (Y/n)?  Y

Deleting cluster micro-sample...done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should see in GKE that the cluster has been deleted.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;Sorry, only Japanese available.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gong023.hatenablog.com/entry/2017/09/21/174819" rel="noopener noreferrer"&gt;雰囲気でgRPC,GKE+kubernetes使ってマイクロサービス作る&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>kubernetes</category>
      <category>googlecloud</category>
      <category>docker</category>
    </item>
    <item>
      <title>Mini gRPC Project (1): Creating a Simple Increment API on Go</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Thu, 15 Oct 2020 09:48:50 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/mini-grpc-project-creating-a-simple-increment-api-on-go-6cn</link>
      <guid>https://dev.to/greenteabiscuit/mini-grpc-project-creating-a-simple-increment-api-on-go-6cn</guid>
      <description>&lt;h1&gt;
  
  
  Objectives
&lt;/h1&gt;

&lt;p&gt;To create an api function that increments the given argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl "http://localhost:8080/increment?val=3"
{"val":4} //the api returns 4
$ curl "http://localhost:8080/increment?val=10"
{"val":11} //the api returns 11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;MacOS Catalina&lt;/li&gt;
&lt;li&gt;Already have gopaths configured&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Download necessary packages
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go get -u github.com/golang/protobuf/protoc-gen-go
$ go get -u github.com/grpc-ecosystem/go-grpc-middleware/logging/zap
$ go get -u go.uber.org/zap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create folders
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;micro-prac$ tree
.
├── proto
│   ├── calc.proto
│   └── gen
│       └── calc.pb.go # will be created using command
└── src
    ├── backend
    │   └── main.go
    └── frontend
        └── main.go

5 directories, 4 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create proto files
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;proto/calc.proto&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// proto/calc.proto

syntax = "proto3";

service Calc {
    rpc Increment(NumRequest) returns (NumResponse) {}
}

message NumRequest {
    int64 val = 1;
}

message NumResponse {
    int64 val = 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the following command in your path (I got some warning but it worked okay).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//create gen folder for string pb.proto files
proto$ mkdir gen

proto$ protoc --go_out=plugins=grpc:gen calc.proto
2020/10/15 18:04:20 WARNING: Missing 'go_package' option in "calc.proto",
  1 package main
please specify it with the full Go package path as
a future release of protoc-gen-go will require this be specified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a &lt;code&gt;calc.pb.go&lt;/code&gt; file created in the &lt;code&gt;gen&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;proto/gen$ cat calc.pb.go
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
//  protoc-gen-go v1.25.0-devel
//  protoc        v3.13.0
// source: calc.proto

package calc

import (
    context "context"
    proto "github.com/golang/protobuf/proto"
    grpc "google.golang.org/grpc"
    codes "google.golang.org/grpc/codes"
    status "google.golang.org/grpc/status"
    protoreflect "google.golang.org/protobuf/reflect/protoreflect"
    protoimpl "google.golang.org/protobuf/runtime/protoimpl"
    reflect "reflect"
    sync "sync"
)

const (
    // Verify that this generated code is sufficiently up-to-date.
    _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
    // Verify that runtime/protoimpl is sufficiently up-to-date.
    _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type NumRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    Val int64 `protobuf:"varint,1,opt,name=val,proto3" json:"val,omitempty"`
}

func (x *NumRequest) Reset() {
    *x = NumRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &amp;amp;file_calc_proto_msgTypes[0]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}

func (x *NumRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}

func (*NumRequest) ProtoMessage() {}

func (x *NumRequest) ProtoReflect() protoreflect.Message {
    mi := &amp;amp;file_calc_proto_msgTypes[0]
    if protoimpl.UnsafeEnabled &amp;amp;&amp;amp; x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}

// Deprecated: Use NumRequest.ProtoReflect.Descriptor instead.
func (*NumRequest) Descriptor() ([]byte, []int) {
    return file_calc_proto_rawDescGZIP(), []int{0}
}

func (x *NumRequest) GetVal() int64 {
    if x != nil {
        return x.Val
    }
    return 0
}

type NumResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    Val int64 `protobuf:"varint,1,opt,name=val,proto3" json:"val,omitempty"`
}

func (x *NumResponse) Reset() {
    *x = NumResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &amp;amp;file_calc_proto_msgTypes[1]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}

func (x *NumResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}

func (*NumResponse) ProtoMessage() {}

func (x *NumResponse) ProtoReflect() protoreflect.Message {
    mi := &amp;amp;file_calc_proto_msgTypes[1]
    if protoimpl.UnsafeEnabled &amp;amp;&amp;amp; x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}

// Deprecated: Use NumResponse.ProtoReflect.Descriptor instead.
func (*NumResponse) Descriptor() ([]byte, []int) {
    return file_calc_proto_rawDescGZIP(), []int{1}
}

func (x *NumResponse) GetVal() int64 {
    if x != nil {
        return x.Val
    }
    return 0
}

var File_calc_proto protoreflect.FileDescriptor

var file_calc_proto_rawDesc = []byte{
    0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1e, 0x0a, 0x0a,
    0x4e, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61,
    0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x1f, 0x0a, 0x0b,
    0x4e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x76,
    0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x32, 0x30, 0x0a,
    0x04, 0x43, 0x61, 0x6c, 0x63, 0x12, 0x28, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65,
    0x6e, 0x74, 0x12, 0x0b, 0x2e, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
    0x0c, 0x2e, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62,
    0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
    file_calc_proto_rawDescOnce sync.Once
    file_calc_proto_rawDescData = file_calc_proto_rawDesc
)

func file_calc_proto_rawDescGZIP() []byte {
    file_calc_proto_rawDescOnce.Do(func() {
        file_calc_proto_rawDescData = protoimpl.X.CompressGZIP(file_calc_proto_rawDescData)
    })
    return file_calc_proto_rawDescData
}

var file_calc_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_calc_proto_goTypes = []interface{}{
    (*NumRequest)(nil),  // 0: NumRequest
    (*NumResponse)(nil), // 1: NumResponse
}
var file_calc_proto_depIdxs = []int32{
    0, // 0: Calc.Increment:input_type -&amp;gt; NumRequest
    1, // 1: Calc.Increment:output_type -&amp;gt; NumResponse
    1, // [1:2] is the sub-list for method output_type
    0, // [0:1] is the sub-list for method input_type
    0, // [0:0] is the sub-list for extension type_name
    0, // [0:0] is the sub-list for extension extendee
    0, // [0:0] is the sub-list for field type_name
}

func init() { file_calc_proto_init() }
func file_calc_proto_init() {
    if File_calc_proto != nil {
        return
    }
    if !protoimpl.UnsafeEnabled {
        file_calc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*NumRequest); i {
            case 0:
                return &amp;amp;v.state
            case 1:
                return &amp;amp;v.sizeCache
            case 2:
                return &amp;amp;v.unknownFields
            default:
                return nil
            }
        }
        file_calc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*NumResponse); i {
            case 0:
                return &amp;amp;v.state
            case 1:
                return &amp;amp;v.sizeCache
            case 2:
                return &amp;amp;v.unknownFields
            default:
                return nil
            }
        }
    }
    type x struct{}
    out := protoimpl.TypeBuilder{
        File: protoimpl.DescBuilder{
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_calc_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   2,
            NumExtensions: 0,
            NumServices:   1,
        },
        GoTypes:           file_calc_proto_goTypes,
        DependencyIndexes: file_calc_proto_depIdxs,
        MessageInfos:      file_calc_proto_msgTypes,
    }.Build()
    File_calc_proto = out.File
    file_calc_proto_rawDesc = nil
    file_calc_proto_goTypes = nil
    file_calc_proto_depIdxs = nil
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// CalcClient is the client API for Calc service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CalcClient interface {
    Increment(ctx context.Context, in *NumRequest, opts ...grpc.CallOption) (*NumResponse, error)
}

type calcClient struct {
    cc grpc.ClientConnInterface
}

func NewCalcClient(cc grpc.ClientConnInterface) CalcClient {
    return &amp;amp;calcClient{cc}
}

func (c *calcClient) Increment(ctx context.Context, in *NumRequest, opts ...grpc.CallOption) (*NumResponse, error) {
    out := new(NumResponse)
    err := c.cc.Invoke(ctx, "/Calc/Increment", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}

// CalcServer is the server API for Calc service.
type CalcServer interface {
    Increment(context.Context, *NumRequest) (*NumResponse, error)
}

// UnimplementedCalcServer can be embedded to have forward compatible implementations.
type UnimplementedCalcServer struct {
}

func (*UnimplementedCalcServer) Increment(context.Context, *NumRequest) (*NumResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method Increment not implemented")
}

func RegisterCalcServer(s *grpc.Server, srv CalcServer) {
    s.RegisterService(&amp;amp;_Calc_serviceDesc, srv)
}

func _Calc_Increment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(NumRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(CalcServer).Increment(ctx, in)
    }
    info := &amp;amp;grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/Calc/Increment",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CalcServer).Increment(ctx, req.(*NumRequest))
  1 // this file is sample for client
    }
    return interceptor(ctx, in, info, handler)
}

var _Calc_serviceDesc = grpc.ServiceDesc{
    ServiceName: "Calc",
    HandlerType: (*CalcServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "Increment",
            Handler:    _Calc_Increment_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
  1 // this file is sample for client
    Metadata: "calc.proto",
}

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create frontend files
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;src/frontend/main.go&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# src/frontend/main.go
// this file is sample for client
package main

import (
    "context"
    "encoding/json"
    "log"
    "net/http"
    "os"
    "strconv"

    "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
    "go.uber.org/zap"
    "google.golang.org/grpc"

    pb "../../proto/gen"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        log.Println("health check")
    })
    http.HandleFunc("/increment", incrementHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
    log.Println("listen started")
}

func incrementHandler(w http.ResponseWriter, r *http.Request) {
    logger, err := zap.NewDevelopment()
    if err != nil {
        log.Fatalf("failed to create logger :%v", err)
    }
    var servName string
    if s := os.Getenv("BACKEND_SERVICE_NAME"); s != "" {
        servName = s
    } else {
        servName = "127.0.0.1"
    }
    logger.Debug("go", zap.String("servName", servName))
    conn, err := grpc.Dial(servName+":8000", grpc.WithInsecure(), grpc.WithUnaryInterceptor(
        grpc_zap.UnaryClientInterceptor(logger),
    ))
    grpc_zap.ReplaceGrpcLogger(logger)
    if err != nil {
        log.Fatalf("failed to connect :%v", err)
    }
    defer conn.Close()

    val, err := strconv.Atoi(r.URL.Query().Get("val"))
    if err != nil {
        logger.Error("got value error", zap.Error(err))
    }
    client := pb.NewCalcClient(conn)
    ctx := context.Background()
    res, err := client.Increment(ctx, &amp;amp;pb.NumRequest{Val: int64(val)})
    if err != nil {
        logger.Error("got error from server", zap.Error(err))
    }
    logger.Info("got response", zap.Int64("value", res.Val))
    b, err := json.Marshal(res)
    if err != nil {
        logger.Error("json parse error", zap.Error(err))
    }
    w.Write(b)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create backend files
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;src/backend/main.go&lt;/code&gt;
&lt;/h2&gt;



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

import (
    "fmt"
    "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
    "go.uber.org/zap"
    "google.golang.org/grpc"
    "log"
    "net"
    pb "../../proto/gen"
    context "golang.org/x/net/context"
)

func main() {
    port := 8000
    logger, err := zap.NewDevelopment()
    if err != nil {
        log.Fatalf("failed to create logger :%v", err)
    }
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
    if err != nil {
        logger.Fatal("failed to listen", zap.Error(err))
    }
    server := grpc.NewServer(grpc.UnaryInterceptor(
        grpc_zap.UnaryServerInterceptor(logger),
    ))
    grpc_zap.ReplaceGrpcLogger(logger)
    pb.RegisterCalcServer(server, &amp;amp;CalcService{})
    server.Serve(lis)
}

type CalcService struct{}

func (s *CalcService) Increment(ctx context.Context, req *pb.NumRequest) (*pb.NumResponse, error) {
    req.Val++
    return &amp;amp;pb.NumResponse{Val: req.Val}, nil
}

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

&lt;/div&gt;



&lt;p&gt;Run the &lt;code&gt;go run main.go&lt;/code&gt; in both backend and frontend.&lt;/p&gt;

&lt;p&gt;When you use curl, you should be able to get a response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the curl commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl "http://localhost:8080/increment?val=10"
{"val":11}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results on frontend side
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend$ go run main.go
2020-10-15T18:21:11.609+0900    DEBUG   frontend/main.go:39 go  {"servName": "127.0.0.1"}
2020-10-15T18:21:11.610+0900    INFO    zap/grpclogger.go:46    [core]Subchannel picks a new address "127.0.0.1:8000" to connect    {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:11.610+0900    INFO    zap/grpclogger.go:46    [core]Channel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:11.612+0900    INFO    zap/grpclogger.go:46    [core]Subchannel Connectivity change to READY   {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:11.613+0900    INFO    zap/grpclogger.go:46    [core]pickfirstBalancer: UpdateSubConnState: 0xc0001ac6e0, {READY &amp;lt;nil&amp;gt;}    {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:11.613+0900    INFO    zap/grpclogger.go:46    [core]Channel Connectivity change to READY  {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:11.616+0900    DEBUG   zap/options.go:203  finished client unary call  {"system": "grpc", "span.kind": "client", "grpc.service": "Calc", "grpc.method": "Increment", "grpc.code": "OK", "grpc.time_ms": 6.538000106811523}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results on backend
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go
2020-10-15T18:21:11.615+0900    INFO    zap/options.go:203  finished unary call with code OK    {"grpc.start_time": "2020-10-15T18:21:11+09:00", "system": "grpc", "span.kind": "server", "grpc.service": "Calc", "grpc.method": "Increment", "grpc.code": "OK", "grpc.time_ms": 0.21799999475479126}
2020-10-15T18:21:11.617+0900    INFO    zap/grpclogger.go:46    [transport]transport: loopyWriter.run returning. connection error: desc = "transport is closing"    {"system": "grpc", "grpc_log": true}
2020-10-15T18:21:15.505+0900    INFO    zap/options.go:203  finished unary call with code OK    {"grpc.start_time": "2020-10-15T18:21:15+09:00", "system": "grpc", "span.kind": "server", "grpc.service": "Calc", "grpc.method": "Increment", "grpc.code": "OK", "grpc.time_ms": 0.023000000044703484}
2020-10-15T18:21:15.506+0900    INFO    zap/grpclogger.go:46    [transport]transport: loopyWriter.run returning. connection error: desc = "transport is closing"    {"system": "grpc", "grpc_log": true}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next: Deployment on GKE
&lt;/h2&gt;

&lt;p&gt;We will deploy this simple gRPC API on GKE here: &lt;a href="https://dev.to/greenteabiscuit/mini-grpc-project-deploying-the-grpc-api-on-k8s-4h15"&gt;Mini gRPC Project (2): Deploying the gRPC API on k8s&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Using Let's Encrypt on AWS EC2 Instance</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Mon, 05 Oct 2020 04:13:30 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/using-let-s-encrypt-on-aws-ec2-instance-2aca</link>
      <guid>https://dev.to/greenteabiscuit/using-let-s-encrypt-on-aws-ec2-instance-2aca</guid>
      <description>&lt;h1&gt;
  
  
  Objectives
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Create a SSL certificate on your EC2 instance.&lt;/li&gt;
&lt;li&gt;We will not consider using php, maria-db on this EC instance (unlike in the documentation).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Documentations
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html#ssl_prereq"&gt;Tutorial: Configure SSL/TLS on Amazon Linux 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, some of the instructions here in the documentation were outdated.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Already launched an EC2 instance (in case of this situation, Amazon Linux 2)&lt;/li&gt;
&lt;li&gt;The EC2 security groups have ports 80, 443, and 22 open (http, https, and ssh respectively).&lt;/li&gt;
&lt;li&gt;Already have a domain created on Route 53 or somewhere else.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Procedures
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Install apache on your EC2 machine
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html"&gt;Tutorial: Install a LAMP web server on Amazon Linux 2&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo yum update -y
$ sudo yum install -y httpd
$ sudo systemctl start httpd
$ sudo systemctl enable httpd
$ sudo systemctl is-enabled httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a localhost.crt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo yum install -y mod_ssl
$ cd /etc/pki/tls/certs
$ sudo ./make-dummy-cert localhost.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; comment out the &lt;code&gt;SSLCertificateKeyFile /etc/pki/tls/private/localhost.key&lt;/code&gt;, although it says so in the documentation. Otherwise, you will get an error when running apache (reason unknown).&lt;/p&gt;

&lt;p&gt;I actually do not know whether this localhost.crt is even necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and run certbot
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
$ sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
$ sudo yum-config-manager --enable epel*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following lines in your &lt;code&gt;/etc/httpd/conf/httpd.conf&lt;/code&gt; and after &lt;code&gt;Listen 80&lt;/code&gt;, insert the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    DocumentRoot "/var/www/html"
    ServerName "example.com"
    ServerAlias "www.example.com"
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart apache, install certbot, and run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo systemctl restart httpd
$ sudo yum install -y certbot python2-certbot-apache
$ sudo certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agree to the terms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose the domain names you want to activate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: example.com
2: www.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, answer to a couple of questions, and you should be done!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Congratulations! You have successfully enabled https://example.com and
https://www.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/certbot.oneeyedman.net/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/certbot.oneeyedman.net/privkey.pem
   Your cert will expire on 2019-08-01. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see your certificates, private key, and chain at &lt;code&gt;/etc/letsencrypt/live/certbot.oneeyedman.net&lt;/code&gt;. You can import these into your Amazon Certificate Manager, and use it for your Elastic Load Balancers.&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;There are other ways to install certbot apart from &lt;code&gt;sudo yum install&lt;/code&gt;, such as &lt;code&gt;curl&lt;/code&gt;. I followed the AWS docs on this one.&lt;/li&gt;
&lt;li&gt;But in case of using &lt;code&gt;curl&lt;/code&gt;, you will have to configure the settings so that it matches the requirements of Amazon Linux 2.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>Tutorial with Docker Swarm and Stack</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Thu, 01 Oct 2020 12:21:58 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/tutorial-with-docker-swarm-and-stack-2b0n</link>
      <guid>https://dev.to/greenteabiscuit/tutorial-with-docker-swarm-and-stack-2b0n</guid>
      <description>&lt;h1&gt;
  
  
  Objectives
&lt;/h1&gt;

&lt;p&gt;We will&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a docker image and push it to docker hub&lt;/li&gt;
&lt;li&gt;Pull the image from the hub and create a stack.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Procedures
&lt;/h1&gt;

&lt;p&gt;First I created a directory as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir docker-stack-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create the &lt;code&gt;Dockerfile&lt;/code&gt;, and some python scripts.&lt;br&gt;
The directory should look like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── Dockerfile
├── app.py
└── requirements.txt

0 directories, 3 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dockerfile is as below.&lt;br&gt;
&lt;/p&gt;

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

FROM python:3.7

WORKDIR /app

ADD . /app

RUN pip install -r requirements.txt

EXPOSE 80

ENV NAME World

CMD ["python", "app.py"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;app.py for python is written as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.py


from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr('counter')
    except RedisError:
        visits = "&amp;lt;i&amp;gt;cannot connect to Redis, counter disabled&amp;lt;/i&amp;gt;"

    html = "&amp;lt;h3&amp;gt;Hello {name}!&amp;lt;/h3&amp;gt;" \
           "&amp;lt;b&amp;gt;Hostname:&amp;lt;/b&amp;gt; {hostname}&amp;lt;br/&amp;gt;" \
           "&amp;lt;b&amp;gt;Visits:&amp;lt;/b&amp;gt; {visits}"
    return html.format(name=os.getenv('NAME', "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

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

&lt;/div&gt;



&lt;p&gt;Finally, the requirements.txt is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# requirements.txt
Flask
Redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will build and run the docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build -t python-server .
Sending build context to Docker daemon   5.12kB
Step 1/7 : FROM python:3.7
 ---&amp;gt; 5c1cd4638fb7
............

$ docker run -p 4000:80 python-server
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to &lt;code&gt;localhost:4000&lt;/code&gt; and you should see this page (For some reason, redis was not working.):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2sWAFXEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kfdhmu4ipqjsk04ujpmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2sWAFXEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kfdhmu4ipqjsk04ujpmi.png" alt="Alt Text" width="447" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see that the container id is &lt;code&gt;99f360ce0c36&lt;/code&gt; here. We will commit the image, and push it to docker hub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker login
Authenticating with existing credentials...
Login Succeeded

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                  NAMES
99f360ce0c36        python-server       "python app.py"     About a minute ago   Up About a minute   0.0.0.0:4000-&amp;gt;80/tcp   keen_galois

$ docker commit 99f360ce0c36 python-server:latest
sha256:9dbcf7df033bb595c6e4c6528dd125716f11355d43dcea4dc8ccbaaced38c44c

$ docker tag python-server:latest USERNAME/python-server:latest

$ docker push USERNAME/python-server:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will create our &lt;code&gt;docker-compose.yml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3"
services:
  web:
    image: USERNAME/python-server:latest
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will initialize the swarm and deploy it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker swarm init
Swarm initialized: current node (nrgwdwv97ioguu0gqq7t19kln) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3lcxtiaau24gw21h2bgkd1ptavl56yczedbcm7d4e865naj8ks-7c5sgf7jh4youa7xsq2l3dt3j 192.168.65.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

$ docker stack deploy -c docker-compose.yml getstartedexample
Creating network getstartedexample_webnet
Creating service getstartedexample_web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see all the nodes here using &lt;code&gt;ps&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker stack ps getstartedexample
ID                  NAME                      IMAGE                                  NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
x3xradislkhr        getstartedexample_web.1   USERNAME/python-server:latest   docker-desktop      Running             Running 12 seconds ago
shlygtlq66e0        getstartedexample_web.2   USERNAME/python-server:latest   docker-desktop      Running             Running 12 seconds ago
uk1wexhimc8a        getstartedexample_web.3   USERNAME/python-server:latest   docker-desktop      Running             Running 12 seconds ago
rijovk7yzr48        getstartedexample_web.4   USERNAME/python-server:latest   docker-desktop      Running             Running 12 seconds ago
avlqa3hxgbt2        getstartedexample_web.5   USERNAME/python-server:latest   docker-desktop      Running             Running 12 seconds ago

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

&lt;/div&gt;



&lt;p&gt;When you access &lt;code&gt;localhost&lt;/code&gt;, you should see the node ids every time you refresh.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MQ57rBZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mhqoctf3w6pgoe9zo6sz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MQ57rBZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mhqoctf3w6pgoe9zo6sz.png" alt="Alt Text" width="388" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dele_NMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7rmwewrxqo59fh6topon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dele_NMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7rmwewrxqo59fh6topon.png" alt="Alt Text" width="381" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the command below to exit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker stack rm getstartedexample
Removing service getstartedexample_web
Removing network getstartedexample_webnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>docker</category>
    </item>
    <item>
      <title>Installing ECS-CLI in your Mac</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Sat, 26 Sep 2020 15:58:42 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/installing-ecs-cli-in-your-mac-15f9</link>
      <guid>https://dev.to/greenteabiscuit/installing-ecs-cli-in-your-mac-15f9</guid>
      <description>&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;MacOS Catalina&lt;br&gt;
More information can be found here in the documentation: &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI_installation.html"&gt;Installing the Amazon ECS CLI&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Procedures
&lt;/h1&gt;

&lt;p&gt;Download ecs-cli using &lt;code&gt;sudo curl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest
Password:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 49.5M  100 49.5M    0     0  3419k      0  0:00:14  0:00:14 --:--:-- 4012k
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install &lt;code&gt;gnupg&lt;/code&gt;, or GNU privacy guard. This may take a few minutes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install gnupg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following command. This will retrieve the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gpg --keyserver hkp://keys.gnupg.net --recv BCE9D9A42D51784F
gpg: directory '/Users/USERNAME/.gnupg' created
gpg: keybox '/Users/USERNAME/.gnupg/pubring.kbx' created
gpg: /Users/USERNAME/.gnupg/trustdb.gpg: trustdb created
gpg: key BCE9D9A42D51784F: public key "Amazon ECS &amp;lt;ecs-security@amazon.com&amp;gt;" imported
gpg: Total number processed: 1
gpg:               imported: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the ECS CLI signatures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -Lo ecs-cli.asc https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest.asc
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   821  100   821    0     0   1080      0 --:--:-- --:--:-- --:--:--  1078

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

&lt;/div&gt;



&lt;p&gt;Verigy the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gpg --verify ecs-cli.asc /usr/local/bin/ecs-cli
gpg: Signature made 水  7/ 8 07:29:27 2020 JST
gpg:                using RSA key DE3CBD61ADAF8B8E
gpg: Good signature from "Amazon ECS &amp;lt;ecs-security@amazon.com&amp;gt;" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: F34C 3DDA E729 26B0 79BE  AEC6 BCE9 D9A4 2D51 784F
     Subkey fingerprint: EB3D F841 E2C9 212A 2BD4  2232 DE3C BD61 ADAF 8B8E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the necessary restrictions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo chmod +x /usr/local/bin/ecs-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are able to check the version, it is successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ecs-cli --version
ecs-cli version 1.20.0 (7547c45)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
    </item>
    <item>
      <title>Creating an App on Elastic Beanstalk from Terminal</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Thu, 24 Sep 2020 09:28:29 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/creating-an-app-on-elastic-beanstalk-from-terminal-26i6</link>
      <guid>https://dev.to/greenteabiscuit/creating-an-app-on-elastic-beanstalk-from-terminal-26i6</guid>
      <description>&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;MacOS Catalina&lt;/li&gt;
&lt;li&gt;Have the ebcli installed&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Initialize the elastic beanstalk application
&lt;/h1&gt;

&lt;p&gt;We will choose docker for the platform.&lt;br&gt;
&lt;/p&gt;

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

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
18) eu-north-1 : EU (Stockholm)
19) eu-south-1 : EU (Milano)
20) ap-east-1 : Asia Pacific (Hong Kong)
21) me-south-1 : Middle East (Bahrain)
22) af-south-1 : Africa (Cape Town)
(default is 3): 1


Select an application to use
1) eb-https
2) Up
3) [ Create new Application ]
(default is 3):


Enter Application Name
(default is "eb-https2"):
Application eb-https2 has been created.
Select a platform.
1) .NET Core on Linux
2) .NET on Windows Server
3) Docker
4) GlassFish
5) Go
6) Java
7) Node.js
8) PHP
9) Packer
10) Python
11) Ruby
12) Tomcat
(make a selection): 3

Select a platform branch.
1) Docker running on 64bit Amazon Linux 2
2) Multi-container Docker running on 64bit Amazon Linux
3) Docker running on 64bit Amazon Linux
(default is 1): 1

Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
Do you want to set up SSH for your instances?
(Y/n): n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create the environment
&lt;/h1&gt;

&lt;p&gt;We will add the --vpc option to create the virtual private cloud.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ eb create --vpc
// press enter
Enter Environment Name
(default is eb-https2-dev):
//press enter
Enter DNS CNAME prefix
(default is eb-https2-dev):

Select a load balancer type
press enter
1) classic
2) application
3) network
(default is 2):

Would you like to enable Spot Fleet requests for this environment?
(y/N): N

Enter the VPC ID: vpc-e3e2079e
Do you want to associate a public IP address? (Y/n): Y

// I entered the same subnets for both the EC2 and ELB subnets.
Enter a comma-separated list of Amazon EC2 subnets: subnet-416eba60, subnet-764a8029
Enter a comma-separated list of Amazon ELB subnets: subnet-416eba60, subnet-764a8029
Do you want the load balancer to be public? (Select no for internal) (Y/n): Y
Enter a comma-separated list of Amazon VPC security groups: sg-01475203460d2c24b
NOTE: The current directory does not contain any source code. Elastic Beanstalk is launching the sample application instead.
Do you want to download the sample application into the current directory?
(Y/n): Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After about 10 minutes, if you are successful, you should see the environment built in your console.&lt;br&gt;
When you access the url, you should see the sample page here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zyohkaz9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tyf5ryttala7nklh5odd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zyohkaz9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tyf5ryttala7nklh5odd.png" alt="Alt Text" width="880" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you chose &lt;code&gt;Y&lt;/code&gt; and downloaded the sample application into the current directory, your folder should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── Dockerfile
├── Dockerrun.aws.json
├── application.py
└── cron.yaml

0 directories, 4 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>docker</category>
    </item>
    <item>
      <title>Deploying a Sample React App to ECS</title>
      <dc:creator>Reishi Mitani</dc:creator>
      <pubDate>Sun, 20 Sep 2020 07:33:02 +0000</pubDate>
      <link>https://dev.to/greenteabiscuit/deploying-a-sample-react-app-to-ecs-4fa7</link>
      <guid>https://dev.to/greenteabiscuit/deploying-a-sample-react-app-to-ecs-4fa7</guid>
      <description>&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;p&gt;To create &amp;amp; deploy a sample react application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MacOS Catalina&lt;/li&gt;
&lt;li&gt;Have the necessary modules for react installed&lt;/li&gt;
&lt;li&gt;Have docker installed&lt;/li&gt;
&lt;li&gt;Have &lt;code&gt;awscli&lt;/code&gt; installed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the react app
&lt;/h2&gt;

&lt;p&gt;Create a react app in terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ create-react-app sample-react-ecs-app
// if not working, try $ npx create-react-app sample-react-ecs-app
$ cd sample-react-ecs-app/
$ touch Dockerfile
$ tree -I node_modules
.
├── Dockerfile
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   └── serviceWorker.js
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contents of Dockerfile is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Dockerfile
FROM node:11-alpine as builder
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN yarn install
COPY . .
RUN yarn build

FROM nginx:1.15-alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build the image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker image build -t sample-react-ecs-app:latest .
Sending build context to Docker daemon  181.6MB
Step 1/10 : FROM node:11-alpine as builder
...
...
...
Successfully built 9a110f83b860
Successfully tagged sample-react-ecs-app:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker images | grep sample-react-ecs-app
sample-react-ecs-app                  latest              9a110f83b860        5 minutes ago       16.6MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the server, and in &lt;code&gt;localhost:80&lt;/code&gt;, you should be able to access the following page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker container run --rm -p 80:80 sample-react-ecs-app:latest
172.17.0.1 - - [20/Sep/2020:06:23:55 +0000] "GET / HTTP/1.1" 200 2247 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36" "-"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4JaYpgGR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/00bj8ylbl4xtij54itnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4JaYpgGR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/00bj8ylbl4xtij54itnx.png" alt="Alt Text" width="880" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurations in ECS
&lt;/h2&gt;

&lt;p&gt;Open the ECS in your AWS console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tgO3VUbm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1845bzqpwx7hgzx98rhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tgO3VUbm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1845bzqpwx7hgzx98rhj.png" alt="Alt Text" width="880" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---sF3Rygz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/trrbrovixbh72x67hizr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---sF3Rygz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/trrbrovixbh72x67hizr.png" alt="Alt Text" width="880" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will name the repository &lt;code&gt;sample-react-ecs-app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FQ18l_H3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dtbwelzjrd345k3bvp2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FQ18l_H3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dtbwelzjrd345k3bvp2g.png" alt="Alt Text" width="880" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the repository page and click &lt;code&gt;view push commands&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LgSF5K8p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oq9dnrrpvff3zwoqf9dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LgSF5K8p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oq9dnrrpvff3zwoqf9dx.png" alt="Alt Text" width="880" height="369"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
$ docker tag sample-react-ecs-app:latest xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-react-ecs-app:latest
$ docker push xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-react-ecs-app:latest
The push refers to repository [xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-react-ecs-app]
83f5a6793760: Pushed
a521e1bbddf5: Pushed
bf381a670956: Pushed
a61993362baf: Pushed
f1b5933fe4b5: Pushed
latest: digest: sha256:eca276a688f71fbf03d0044354ab5d693cd9090d2497b9e0c3d37ef2bd25ca2b size: 1363
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your own container in the ECS repository.&lt;/p&gt;

&lt;p&gt;Next, we will create the cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WKFWMX_I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6uz6kyaor4spialoz9u3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WKFWMX_I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6uz6kyaor4spialoz9u3.png" alt="Alt Text" width="672" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will select the EC2 Linux + Network version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R3mEofeD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viewvep11f73ll6a9w8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R3mEofeD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viewvep11f73ll6a9w8d.png" alt="Alt Text" width="880" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will name the cluster &lt;code&gt;sample-react-ecs-app-cluster&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KUn_F2uc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/etq6s7tuli5lfeeycgnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KUn_F2uc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/etq6s7tuli5lfeeycgnk.png" alt="Alt Text" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the cluster newly created in the AWS console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H-tGdi6Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e763de0yf217ai9h1ff2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H-tGdi6Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e763de0yf217ai9h1ff2.png" alt="Alt Text" width="880" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The situation of the clusters can be found in the cluster page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dsdMKF5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kw32z7e6eyqiu9cd7yt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dsdMKF5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kw32z7e6eyqiu9cd7yt8.png" alt="Alt Text" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we will click on the &lt;code&gt;task definitions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6_1HjB-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/469x2v50vlhzye1wfg70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6_1HjB-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/469x2v50vlhzye1wfg70.png" alt="Alt Text" width="233" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will add the task as below, called &lt;code&gt;sample-react-ecs-app-task&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZvS4TjKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v20t3s4cnque608wtifq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZvS4TjKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v20t3s4cnque608wtifq.png" alt="Alt Text" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v6-RFu6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/net6r88rbss0k1mvhy2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v6-RFu6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/net6r88rbss0k1mvhy2n.png" alt="Alt Text" width="880" height="702"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we will run the tasks on our cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rpxa4Ml9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/adt803ubcsv8w3y25243.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rpxa4Ml9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/adt803ubcsv8w3y25243.png" alt="Alt Text" width="880" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the tasks are running on the cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A_YH9Lca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/shn5hkxj5zekbyr2g2oi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A_YH9Lca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/shn5hkxj5zekbyr2g2oi.png" alt="Alt Text" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And our sample website is running on the port 32768.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xISB5t2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sqt5dxi82xl7hx4cg84j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xISB5t2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sqt5dxi82xl7hx4cg84j.png" alt="Alt Text" width="880" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I skipped on some parts, and I hope to update this article as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Sorry, only Japanese available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://casualdevelopers.com/tech-tips/how-to-deploy-dockerized-react-application-to-aws-with-ecr-and-ecs-ec2/#i-2"&gt;AWS ECRとECSの入門(EC2編) ~ ECSのEC2版を使ってReactのDockerアプリケーションをAWS上で稼働させる方法 ~&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>react</category>
    </item>
  </channel>
</rss>
