<?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: Liem Le Hoang Duc</title>
    <description>The latest articles on DEV Community by Liem Le Hoang Duc (@liemle3893).</description>
    <link>https://dev.to/liemle3893</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%2F203134%2Fc13361f0-418c-4293-b9f0-21fea2757375.jpeg</url>
      <title>DEV Community: Liem Le Hoang Duc</title>
      <link>https://dev.to/liemle3893</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liemle3893"/>
    <language>en</language>
    <item>
      <title>HashiCorp Nomad Introduction</title>
      <dc:creator>Liem Le Hoang Duc</dc:creator>
      <pubDate>Wed, 01 Apr 2020 11:42:42 +0000</pubDate>
      <link>https://dev.to/liemle3893/hashicorp-nomad-in-actions-3kbi</link>
      <guid>https://dev.to/liemle3893/hashicorp-nomad-in-actions-3kbi</guid>
      <description>&lt;h3&gt;
  
  
  Oh, yeah???
&lt;/h3&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ntIlR45D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EEcyRIcW4AAKnaN.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fugn4WqE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/539085612402221056/5T4TaHaC_normal.png" alt="Daniele Polencic profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Daniele Polencic
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/danielepolencic"&gt;@danielepolencic&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Are you running your own bare-metal Kubernetes cluster?&lt;br&gt;&lt;br&gt;I feel you. 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      19:53 PM - 14 Sep 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1172961505144377350" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1172961505144377350" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      37
      &lt;a href="https://twitter.com/intent/like?tweet_id=1172961505144377350" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      130
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;P/s: I'm not telling to use &lt;a href="https://nomadproject.io"&gt;HashiCorpNomad&lt;/a&gt; and abandoned K8S, but at least, take a look at it, you may think God is not abandoned you, no more!&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nomad is the project from HashiCorp, a company that help me, and a lot of other guys, working with Cloud more easily.&lt;/li&gt;
&lt;li&gt;It was a workload orchestrator.&lt;/li&gt;
&lt;li&gt;It support container application, legacy application, Java, Batch Job, QEMU.&lt;/li&gt;
&lt;li&gt;It's easy to operate and maintain.&lt;/li&gt;
&lt;li&gt;It had less magic than k8s, actually, no magics.&lt;/li&gt;
&lt;li&gt;It's may be what you want from the very beginning but other guys just bark about K8S and told you to use K8S.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You're working with legacy system, which is not ready to one-step move to Cloud.&lt;/li&gt;
&lt;li&gt;You're not familiar with Orchestrator and Containerized application.&lt;/li&gt;
&lt;li&gt;You're not familiar with Cloud, or you don't want to learn K8S.&lt;/li&gt;
&lt;li&gt;You cannot use K8S because you don't have an OPs team, and your country don't have a K8S provider which you trusted.&lt;/li&gt;
&lt;li&gt;You want to try out something differences than K8S.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Facts
&lt;/h2&gt;

&lt;p&gt;In facts, some company combine K8S and Nomad together to handle their workload. Learn about it &lt;a href="https://github.com/kelseyhightower/nomad-on-kubernetes"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Terms
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Nomad Server
&lt;/h4&gt;

&lt;p&gt;This one will operate and checking the state of system. For example:&lt;br&gt;
"Is this app in state that user defined?" If not, reschedule it!&lt;br&gt;
"I need 1GB of RAM for my app, can you handle it?" Agent-X have enough memory, Ok, I will run your app on it!&lt;/p&gt;

&lt;p&gt;To start a nomad server:&lt;br&gt;
&lt;code&gt;nomad agent -server -bind=0.0.0.0 -data-dir=/tmp/nomad-server&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Nomad Agent
&lt;/h4&gt;

&lt;p&gt;This one will listen to Server request and reporting the state of application to Server, if the state of the application is abnormal, Server will request Agent to stop/start/restart the application.&lt;/p&gt;

&lt;p&gt;To start a nomad agent:&lt;br&gt;
&lt;code&gt;nomad agent -agent -data-dir=/tmp/nomad-agent&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;em&gt;Notes&lt;/em&gt;:
&lt;/h4&gt;

&lt;p&gt;On local machine, I usually use &lt;code&gt;nomad agent -dev&lt;/code&gt; to bootstrap nomad cluster. Think about K8S 🙃&lt;/p&gt;
&lt;h4&gt;
  
  
  Job
&lt;/h4&gt;

&lt;p&gt;Is the configuration which is defined the &lt;code&gt;expected state&lt;/code&gt;, which you want your app into.&lt;/p&gt;

&lt;p&gt;A job file usually have following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;job
  \_ group
        \_ task
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  Group
&lt;/h4&gt;

&lt;p&gt;Is a collection of application which will be scheduled on the same Agent.&lt;br&gt;
Application in the same group can be shared volume and network (using Consul Connect).&lt;br&gt;
&lt;em&gt;Pro tips&lt;/em&gt;: Using &lt;code&gt;group&lt;/code&gt; as your unit of scaling.&lt;br&gt;
&lt;em&gt;Bonus&lt;/em&gt; For people come from K8S, using group as your &lt;code&gt;Pod&lt;/code&gt; will be good enough. Combine group with difference type of Job will provide things similar to Deployment, DaemonSet.&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Task
&lt;/h4&gt;

&lt;p&gt;Is a unit of work which was your application. Say container, binary, Java app.&lt;br&gt;
&lt;em&gt;Pro tips&lt;/em&gt;: Naming your task follow your job will help you debug and managing/monitoring application more easily and friendly. Eg: Your job name is "example", then your nginx should named "example-nginx".&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Service
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: This is a bit out of Nomad, becuz you will need Consul to let this work. But, who use Nomad without Consul?&lt;br&gt;
After you start your application, say, an API and you want to populate its address to other services over Consul, you can use this stanza instead of self register inside your code.&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;p&gt;That enough for the introduction. As a developer, you can get use of Nomad right away.&lt;br&gt;
In the next post, I will show you how to create a website using Docker, Traefik and Nomad.&lt;/p&gt;

&lt;h3&gt;
  
  
  For people who dont have patience. Come &lt;a href="https://github.com/liemle3893/nomad-getting-started"&gt;here&lt;/a&gt; with a full source code how to deploy a web using Nomad, Traefik and Docker as well as how to bootstrap Nomad Cluster using Ansible.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/liemle3893/nomad-getting-started"&gt;https://github.com/liemle3893/nomad-getting-started&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nomad</category>
      <category>orchestrator</category>
      <category>container</category>
    </item>
    <item>
      <title>Docker basics</title>
      <dc:creator>Liem Le Hoang Duc</dc:creator>
      <pubDate>Wed, 01 Apr 2020 10:46:50 +0000</pubDate>
      <link>https://dev.to/liemle3893/docker-basics-mkh</link>
      <guid>https://dev.to/liemle3893/docker-basics-mkh</guid>
      <description>&lt;p&gt;I'm here to share and well as to note some basics about Docker.&lt;br&gt;
I'm Java developer, so I will mapping the concept from Java to Docker. If something confused you, please add comment and I will answer/update accordingly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Terms
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Docker Machine
&lt;/h4&gt;

&lt;p&gt;The host/machine which is run docker server.&lt;br&gt;
If you run Docker on Mac you will have a Virtual Machine which is, in this case, a Docker Machine&lt;/p&gt;
&lt;h4&gt;
  
  
  Image
&lt;/h4&gt;

&lt;p&gt;Similar to Java, you packaged your app into Jar/War file and then your server will run it. &lt;br&gt;
Similar to Docker, Image is a type of package that contains all of your things extras some OS files (/usr/bin, etc...).&lt;/p&gt;
&lt;h4&gt;
  
  
  Container
&lt;/h4&gt;

&lt;p&gt;From Java point, you have Jar/War file, then you run it by &lt;code&gt;java -jar your-jar.jar&lt;/code&gt;. The Java Runtime will starting to run your bytecode and you have a process.&lt;br&gt;
Same for Docker, when you type &lt;code&gt;docker run your-image&lt;/code&gt;, the docker runtime (currently default is runc) will start to run your &lt;strong&gt;&lt;em&gt;image&lt;/em&gt;&lt;/strong&gt; and create a process, which is, in docker terms - container.&lt;/p&gt;
&lt;h4&gt;
  
  
  Tag
&lt;/h4&gt;

&lt;p&gt;Tagging or Versioning is always important.&lt;br&gt;
When I was using Java, I just created my Jar/War and then Upload it to repository, say, version &lt;code&gt;1.0.0-RELEASE&lt;/code&gt; then the Ops guys will download that file from Repository and Run it.&lt;br&gt;
In Docker, I have an &lt;code&gt;image&lt;/code&gt;, I &lt;code&gt;tag&lt;/code&gt; it, and then I &lt;code&gt;push&lt;/code&gt; it into repository.&lt;br&gt;
Tag is just the &lt;strong&gt;&lt;em&gt;&lt;em&gt;old wine in new bottle&lt;/em&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Volume
&lt;/h4&gt;

&lt;p&gt;In Java, most of the time you will read/write file directly on Host Machine/Server and usually, that file will remain until you delete it. &lt;br&gt;
In Docker, every time start a new container, the file system is fresh, none of your files from previous session will remain. This is a so-called "immutable". To solve that problem, Docker have a concept called &lt;em&gt;volume&lt;/em&gt;.&lt;br&gt;
To bind a volume inside Docker, simply add option &lt;code&gt;--volume&lt;/code&gt; or &lt;code&gt;-v&lt;/code&gt; for short.&lt;/p&gt;
&lt;h2&gt;
  
  
  Frequency used commands
&lt;/h2&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;docker run&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Start a container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; /tmp:/tmp/host ubuntu:18.04
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In above command:&lt;br&gt;
&lt;code&gt;--rm&lt;/code&gt; mean: after this container finish execute, clean it! &lt;br&gt;
&lt;code&gt;it&lt;/code&gt; mean: Interactive shell. Without this, if your application require you to input, you cannot do it.&lt;br&gt;
&lt;code&gt;-P&lt;/code&gt; mean: If this container &lt;code&gt;EXPOSE&lt;/code&gt; ports, please expose all of those ports randomly on DockerMachine. To bind specific port, 1323 for example. &lt;code&gt;-p 11323:1323&lt;/code&gt;. Where 11323 is the port on Host Machine, and 1323 is port expose by container.&lt;br&gt;
&lt;code&gt;-v /tmp:/tmp/host&lt;/code&gt; mean: bind "/tmp" from host volume to "/tmp/host" in container.&lt;br&gt;
Other useful options:&lt;br&gt;
&lt;code&gt;-d&lt;/code&gt;: Run container in detached mode. You shell will be freed immediately &lt;br&gt;
&lt;code&gt;--name&lt;/code&gt;: Name your container, then use can interact with its.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;docker logs&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; my-nginx &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 38080:80 &lt;span class="nt"&gt;-d&lt;/span&gt; nginx:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Then &lt;code&gt;curl 127.0.0.1:38080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally, to see access log of Nginx. &lt;code&gt;docker logs my-nginx&lt;/code&gt;&lt;br&gt;
Above command will print full logs of &lt;code&gt;my-nginx&lt;/code&gt; container. To limit and follow limited line of logs, use &lt;code&gt;docker logs --follow --tail 10 my-nginx&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;docker exec&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; my-nginx /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This command is very useful to debug our code.&lt;br&gt;
"Is my code created file as I expected?"&lt;br&gt;
"How do I know if my code have all it dependencies? &lt;code&gt;ldd my-binary&lt;/code&gt;!"&lt;br&gt;
Using &lt;code&gt;docker exec&lt;/code&gt; give you the same power as &lt;code&gt;ssh&lt;/code&gt; to your server.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;docker pull&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker pull containous/whoami
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Will download &lt;code&gt;containous/whoami:latest&lt;/code&gt; image to your machine. &lt;br&gt;
To break down &lt;code&gt;docker run&lt;/code&gt;, like we do in git.&lt;br&gt;
&lt;code&gt;git clone&lt;/code&gt; = &lt;code&gt;git init&lt;/code&gt; + &lt;code&gt;git remote add&lt;/code&gt; + &lt;code&gt;git pull&lt;/code&gt;&lt;br&gt;
&lt;code&gt;docker run&lt;/code&gt; = &lt;code&gt;docker pull&lt;/code&gt; + &lt;code&gt;docker container create&lt;/code&gt;  + &lt;code&gt;docker container start&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  After testing and learning, now it's time to create our own docker image.
&lt;/h3&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;docker build&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Here my file template for almost every project (Golang)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; BASE_IMAGE=gcr.io/distroless/base&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:1.14 as builder&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /work&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /work&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 go build &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-ldflags&lt;/span&gt; &lt;span class="s1"&gt;'-extldflags "-static"'&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; app main.go


&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; $BASE_IMAGE&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; maintainer="contact@liemlhd.com"&lt;/span&gt;
&lt;span class="c"&gt;# Copy Built App&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder --chown=65532:65532 /work/app /app/app&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; nonroot&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 1323&lt;/span&gt;

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["./app"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# To build production image&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; saboteurkid/go-demo:latest &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# To build test/dev image&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; saboteurkid/go-demo:latest-debug &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--build-arg&lt;/span&gt; &lt;span class="nv"&gt;BASE_IMAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;saboteurkid/ubuntu:18.04-base &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;docker push&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Finally, Push you Image to the Repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker push saboteurkid/go-demo:latest
&lt;span class="nv"&gt;$ &lt;/span&gt;docker push saboteurkid/go-demo:latest-debug 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Some others useful commands:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docker tag&lt;/code&gt;: this is useful when you want to rename a tag to difference name. Say I want to fork a &lt;code&gt;saboteurkid/go-demo:1.0.0&lt;/code&gt; version from &lt;code&gt;saboteurkid/go-demo:latest&lt;/code&gt;. Simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker tag saboteurkid/go-demo:latest saboteurkid/go-demo:1.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;docker commit&lt;/code&gt;: this is useful when you want to &lt;em&gt;commit your changes&lt;/em&gt; after add some changes to your container. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker exec my-nginx cp /etc/hosts /tmp/hosts
$ docker commit my-nginx saboteurkid/nginx-with-text-file
$ docker run --rm -it -d --name nginx-with-file saboteurkid/nginx-with-text-file
$ docker exec nginx-with-file cat /tmp/file.txt | head -n1 
$ # Will show: `127.0.0.1 localhost`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>docker</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
