<?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: Raftt</title>
    <description>The latest articles on DEV Community by Raftt (@raftt).</description>
    <link>https://dev.to/raftt</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%2F859859%2F28e2d599-bf93-499c-84b6-3a06a9595ccf.png</url>
      <title>DEV Community: Raftt</title>
      <link>https://dev.to/raftt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/raftt"/>
    <language>en</language>
    <item>
      <title>Inside Container Debugging with GO</title>
      <dc:creator>Raftt</dc:creator>
      <pubDate>Tue, 31 May 2022 13:38:03 +0000</pubDate>
      <link>https://dev.to/raftt/inside-container-debugging-with-go-48c5</link>
      <guid>https://dev.to/raftt/inside-container-debugging-with-go-48c5</guid>
      <description>&lt;p&gt;As developers, a good amount of our time is spent debugging. But sometimes, due to setup constraints and a lack of debugging tools for container development, it just isn’t possible.&lt;/p&gt;

&lt;p&gt;When working locally, all you have to do is click &lt;em&gt;Debug&lt;/em&gt; and everything works like magic.&lt;/p&gt;

&lt;p&gt;When dealing with a remote environment or running inside containers, however, we no longer have the &lt;em&gt;Debug&lt;/em&gt; option and we can’t even compile the binary in debug mode.&lt;/p&gt;

&lt;p&gt;Some IDEs try to solve this problem, but most of the time their solution isn’t good enough so we are stuck relying on ad-hoc logging.&lt;/p&gt;

&lt;p&gt;The real issue is that containers aren’t built for active development. They raise barriers around restarting processes, re-compiling binaries on the fly, and otherwise dynamically modifying the runtime. As a result, working with containerized environments is cumbersome, and we spend a bunch of time on workarounds:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. We can add logs and rebuild the image
&lt;/h2&gt;

&lt;p&gt;Because debugging takes so long to setup, we might give up. Instead, we iterate by adding additional ad-hoc logging around the area we are developing. Not only do we get limited information, but our cycle time is super long, since building the image and re-deploying the container (whether locally or remote) can take minutes instead of seconds.&lt;/p&gt;

&lt;p&gt;Sometimes this is the best option... if we end up finding the bug in few iterations - otherwise, we’ll end up making progress, but very slowly. The problem is that you can never know how many iterations it will take, and usually we underestimate ;).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. We can de-containerize the service we are currently developing
&lt;/h2&gt;

&lt;p&gt;Leaving all the other containers in the environment up, we can remove stop the container with the service we are currently developing, and run it locally. This allows us to debug and run with great built-in-IDE tooling!&lt;/p&gt;

&lt;p&gt;Unfortunately, this means we need to have a working local setup for all of the containers we develop, and if we have more than a few - keeping these working can be a hassle. We also may need to handle proxying the network traffic using tools like telepresence. We also need to remember to re-containerize it when we are done, or we end up with a very inconsistent setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. We can debug inside the container by installing the required dependencies in the image, and re-building the binary
&lt;/h2&gt;

&lt;p&gt;This is the most scalable approach to debugging inside containers as, following a one-time setup cost, allows fast iterations and full debugging capabilities.&lt;/p&gt;

&lt;p&gt;We’ll dive deep into option #3 and explore how to debug GO code inside the container. To make this work, we’ll need to install the debugging infrastructure (delve) and the toolchain so we can compile within the container.&lt;/p&gt;

&lt;h1&gt;
  
  
  Debugging with GO inside a running container
&lt;/h1&gt;

&lt;p&gt;Let’s start with a simple example of a containerized Go service, and make the necessary changes to debug the service using Delve:&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.18-alpine3.15 as builder

WORKDIR /code/
COPY ./go.mod ./go.sum /code/
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .
RUN go build -o /code/build/server main.go

FROM alpine:3.15
COPY --from=builder /code/build/server /server

ENTRYPOINT ["/server"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Change how you build the binary
&lt;/h2&gt;

&lt;p&gt;As a first step, let’s modify the &lt;code&gt;go build&lt;/code&gt; command so it keeps the debug symbols in the resulting binary:&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.18-alpine3.15 as builder

WORKDIR /code/
COPY ./go.mod ./go.sum /code/
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .
RUN go build -gcflags "all=-N -l" -o /code/build/server main.go

FROM alpine:3.15
COPY --from=builder /code/build/server /server

ENTRYPOINT ["/server"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Install the required dependencies(such as Delve)
&lt;/h2&gt;

&lt;p&gt;Next, let’s install Delve -&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.18-alpine3.15 as builder

RUN apk add build-base
RUN go install github.com/go-delve/delve/cmd/dlv@latest

WORKDIR /code/
COPY ./go.mod ./go.sum /code/
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .
RUN go build -gcflags "all=-N -l" -o /code/build/server main.go

FROM alpine:3.15
COPY --from=builder /go/bin/dlv /
COPY --from=builder /code/build/server /

ENTRYPOINT ["/server"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Run the process with dlv - so we can actually debug!
&lt;/h2&gt;

&lt;p&gt;Finally, change the entrypoint to the Delve executable we copied over, and configure it to act as a debug server for our binary.&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.18-alpine3.15 as builder

RUN apk add build-base
RUN go install github.com/go-delve/delve/cmd/dlv@latest

WORKDIR /code/
COPY ./go.mod ./go.sum /code/
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .
RUN go build -gcflags "all=-N -l" -o /code/build/server main.go

FROM alpine:3.15
COPY --from=builder /go/bin/dlv /
COPY --from=builder /code/build/server /

EXPOSE 2345
ENTRYPOINT ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", \
            "--accept-multiclient", "exec", "/server"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Container debugging, like it’s local
&lt;/h2&gt;

&lt;p&gt;In the world of R&amp;amp;D, it’s so crucial to have efficient and easy-to-use dev environments and workflows so we can work frustration-free. The length of the development cycle (from code change to feedback) is a critical component, and debugging gives us very rich feedback for a given code change.&lt;br&gt;
But the lack of support in debugging tools within containerized environments themselves brings constant distractions and halts the workflow and thinking process of your people.&lt;/p&gt;

&lt;p&gt;That’s why having the ability - and the simplicity - of debugging in containerized services as if they were local can provide immense benefits for your teams.&lt;/p&gt;

&lt;p&gt;Even if containers were never intended to be used by dev in such a fashion, with Raftt, debugging containerized services becomes as easy as running it natively on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  About &lt;a href="https://www.raftt.io/"&gt;Raftt&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Raftt creates modern flexible environments synced with your tools, features and workflows so you can explore and develop freely. Our cloud platform liberates you from the limitations of your hardware, allowing you to spawn an unlimited number of environments, collaborate and share, and enjoy stability, consistency, and performance.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>docker</category>
      <category>kubernetes</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What are the dev challenges with M1/ARM Macbooks ?</title>
      <dc:creator>Raftt</dc:creator>
      <pubDate>Sun, 22 May 2022 06:18:52 +0000</pubDate>
      <link>https://dev.to/raftt/what-are-the-dev-challenges-with-m1arm-macbooks--1k8f</link>
      <guid>https://dev.to/raftt/what-are-the-dev-challenges-with-m1arm-macbooks--1k8f</guid>
      <description>&lt;p&gt;Any difficulties you experience while developing/debugging in your local dev env since Mac shifted &lt;strong&gt;from x86/Intel to M1/ARM processors&lt;/strong&gt;?&lt;br&gt;
Does that affect your dev workflow?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>cloud</category>
      <category>docker</category>
    </item>
    <item>
      <title>Try an easier way to code in containerized envs with Raftt 🎯 🐳</title>
      <dc:creator>Raftt</dc:creator>
      <pubDate>Mon, 09 May 2022 12:51:34 +0000</pubDate>
      <link>https://dev.to/raftt/theres-an-easier-way-to-code-in-containerized-envs-with-raftt-3d4b</link>
      <guid>https://dev.to/raftt/theres-an-easier-way-to-code-in-containerized-envs-with-raftt-3d4b</guid>
      <description>&lt;p&gt;Our solution helps devs with the frustrations of configuring, maintaining, and sharing development environments on local machine. &lt;/p&gt;

&lt;p&gt;✓ Get remote dev envs created in a single command &lt;br&gt;
✓ Share your entire environment with a single URL &lt;br&gt;
✓ Debug remote containers interactively just as if they were run locally&lt;/p&gt;

&lt;p&gt;Try our free version today &amp;gt;&amp;gt; &lt;a href="https://docs.raftt.io/docs/basics/quickstart"&gt;https://docs.raftt.io/docs/basics/quickstart&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>startup</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
