<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyeonu_wrld.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 02 May 2024 09:54:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hyeonu_wrld.log</title>
            <url>https://velog.velcdn.com/images/hyeonu_wrld/profile/c9042d7a-e488-42b8-a896-f6bc01346acc/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hyeonu_wrld.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyeonu_wrld" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[GitHub Actions를 통한 Spring CI/CD 구축(feat. docker & ghcr)]]></title>
            <link>https://velog.io/@hyeonu_wrld/GitHub-Actions%EB%A5%BC-%ED%86%B5%ED%95%9C-CICD-%EA%B5%AC%EC%B6%95feat.-docker-ghcr</link>
            <guid>https://velog.io/@hyeonu_wrld/GitHub-Actions%EB%A5%BC-%ED%86%B5%ED%95%9C-CICD-%EA%B5%AC%EC%B6%95feat.-docker-ghcr</guid>
            <pubDate>Thu, 02 May 2024 09:54:00 GMT</pubDate>
            <description><![CDATA[<p>학교 전공 수업에서 Spring Boot 애플리케이션을 배포할 일이 생겨 간단하게 GitHub Actions와 Docker를 통해 자동 배포 환경을 구축해보았습니다</p>
<h2 id="yaml">YAML</h2>
<p>완성된 전체 yaml 파일은 다음과 같습니다</p>
<pre><code class="language-yaml">name: Java CI with Gradle

on:
  push:
    branches: [&quot;main&quot;]
  pull_request:
    branches: [&quot;main&quot;]

jobs:
  build-docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

     - name : Setup Environment
       run : |
          echo -e &quot;\n${{ secrets.APPLICATION }}&quot; &gt;&gt; ./src/main/resources/application.properties

      - name: Setup JDK 21
        uses: actions/setup-java@v4
        with:
          distribution: &#39;corretto&#39;
          java-version: &#39;21&#39;

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build

      - name: Set up Docker
        uses: docker/setup-buildx-action@v3

      - name: Login to ghcr
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: yunuo46
          password: ${{ secrets.GHCR_TOKEN }}

      - name: docker Build and Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ghcr.io/yunuo46/getaguitar:latest

  deploy-docker:
    needs: build-docker
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Deploy to Server via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            echo ${{ secrets.GHCR_TOKEN }} | docker login ghcr.io -u yunuo46 --password-stdin
            docker pull ghcr.io/yunuo46/getaguitar:latest
            docker stop getaguitar || true
            docker rm getaguitar || true
            docker run -d --name getaguitar -p 3000:3000 ghcr.io/yunuo46/getaguitar:latest</code></pre>
<h3 id="trigger">Trigger</h3>
<pre><code class="language-yaml">on:
  push:
    branches: [&quot;main&quot;]
  pull_request:
    branches: [&quot;main&quot;]</code></pre>
<p>워크플로우에 대한 트리거를 지정합니다
main branch에 push, pull_request될 경우에 동작하도록 했습니다</p>
<h3 id="checkout">Checkout</h3>
<pre><code class="language-yaml">runs-on: ubuntu-latest
steps:
   - name: Checkout
     uses: actions/checkout@v4
</code></pre>
<p>최신 버전의 Ubuntu Linux Runner에서 실행되도록 했습니다
Runner는 GitHub에서 제공하는 워크플로우를 실행할 수 있는 서버입니다
<code>actions/checkout</code>을 통해 해당 서버에 소스코드를 올릴 수 있습니다</p>
<h3 id="set-up">Set Up</h3>
<pre><code class="language-yaml">- name : Setup Environment
       run : |
          echo -e &quot;\n${{ secrets.APPLICATION }}&quot; &gt;&gt; ./src/main/resources/application.properties

- name: Setup JDK 21
  uses: actions/setup-java@v4
  with:
       distribution: &#39;corretto&#39;
       java-version: &#39;21&#39;

 - name: Setup Gradle
   uses: gradle/actions/setup-gradle@v3</code></pre>
<p>환경변수를 설정해주고
Runner 환경을 로컬 환경과 동일하게 세팅해줍니다</p>
<ul>
<li>JDK 버전과 distribution</li>
<li>gradle 버전<blockquote>
<p><code>gradle/actions/setup-gradle@v3</code>에서 gradle 버전을 따로 지정하지 않아도 버전이 동일해서 찾아보니 default로 wrapper의 설정을 사용한다고 합니다!
참고 : <a href="https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#build-with-a-specific-gradle-version">https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#build-with-a-specific-gradle-version</a></p>
</blockquote>
</li>
</ul>
<h3 id="gradle-build">Gradle Build</h3>
<pre><code class="language-yaml">- name: Grant execute permission for gradlew
  run: chmod +x gradlew

- name: Build with Gradle
  run: ./gradlew build
</code></pre>
<p>window는 기본 권한이 644로 생성되기 때문에 gradlew에 실행권한을 주고 build합니다</p>
<h3 id="push-image-to-ghcrio">Push Image to ghcr.io</h3>
<pre><code class="language-yaml">- name: Set up Docker
        uses: docker/setup-buildx-action@v3

- name: Login to ghcr
  uses: docker/login-action@v3
  with:
       registry: ghcr.io
       username: yunuo46
       password: ${{ secrets.GHCR_TOKEN }}

- name: docker Build and Push
  uses: docker/build-push-action@v5
  with:
       context: .
       push: true
       tags: ghcr.io/yunuo46/getaguitar:latest</code></pre>
<p>Docker를 셋업하고, github container registry에 로그인합니다 
이후 Docker Image를 Build하고 ghcr에 Push합니다
<img src="https://velog.velcdn.com/images/hyeonu_wrld/post/da81f239-b118-4a8c-85d9-c478c8ca0cc3/image.png" alt=""> 이 작업이 완료되면 pakage에 해당 image가 private로 올라가 있는 것을 확인할 수 있습니다
docker hub는 1개의 이미지만 private로 가능한 반면에, ghcr은 500MB까지 무료입니다</p>
<h3 id="deploy-to-server">Deploy to Server</h3>
<pre><code class="language-yaml">- name: Deploy to Server via SSH
  uses: appleboy/ssh-action@master
  with:
       host: ${{ secrets.SERVER_HOST }}
       username: ${{ secrets.SERVER_USERNAME }}
       key: ${{ secrets.SSH_PRIVATE_KEY }}
       port: ${{ secrets.SSH_PORT }}
       script: |
            echo ${{ secrets.GHCR_TOKEN }} | docker login ghcr.io -u yunuo46 --password-stdin
            docker pull ghcr.io/yunuo46/getaguitar:latest
            docker stop getaguitar || true
            docker rm getaguitar || true
            docker run -d --name getaguitar -p 3000:3000 ghcr.io/yunuo46/getaguitar:latest</code></pre>
<p>서버에 ssh로그인을 한 뒤, ghcr에 접속해 최신 image를 pull하고 기존에 존재하는 container를 삭제한 뒤 run해줍니다</p>
<h2 id="dockerfile">Dockerfile</h2>
<p>Dokerfile은 container 실행 시 빌드된 jar파일을 실행하도록 작성했습니다</p>
<pre><code>FROM bellsoft/liberica-openjdk-alpine:21

WORKDIR /app

COPY ./build/libs/*.jar app.jar

EXPOSE 3000

ENTRYPOINT [&quot;java&quot;,&quot;-jar&quot;,&quot;app.jar&quot;]</code></pre><h2 id="트러블-슈팅">트러블 슈팅</h2>
<h3 id="gradle-build-위치">gradle build 위치</h3>
<p>spring boot 환경에서 CI/CD를 구성하는게 처음이라 다양한 글들을 참고하며 구축했습니다
그런데 gradle build를 Dockerfile에서(서버에서) 하는 글을 보기도 해서, github actions에서 build하는 것과 어느 쪽이 맞는 방향인 지 헷갈려서 조금 헤멨던 것 같습니다
결론은 github-hosted runner에서 build하는 것이 CI의 장점을 활용한다고 볼 수 있습니다
변동이 생길 수 있는 서버 환경과 달리 Runner에서는 build환경을 일관성 있게 구축할 수 있고, build가 성공한 경우만 image를 push함으로서 안정적인 배포 또한 가능합니다
그리고 서버 환경에 불필요한 베이스 이미지들과 Layer를 제외하고 아래와 같이 jar파일만 갖고 실행하면 되도록 구성함으로써 이미지의 크기를 줄이고 서버의 부담을 줄일 수 있습니다</p>
<p><img src="https://velog.velcdn.com/images/hyeonu_wrld/post/cf271581-f5bd-4492-a57e-c8bbeec32a0c/image.png" alt=""></p>
<h3 id="plain-jar-생성-방지">plain jar 생성 방지</h3>
<p>Dockerfile에서 COPY명령문 실행 시 executable jar를 복사해야합니다
plain.jar 파일이 생성되지 않도록 build.gradle에 옵션을 추가했습니다</p>
<pre><code>jar {
    enabled = false
}</code></pre><h2 id="느낀-점">느낀 점</h2>
<p>최대한 github문서들을 참고하며 개발하다보니 github actions의 동작 과정에 대해 깊이 이해할 수 있었습니다
추가로 Gradle Caching이나 bootbuildimage, qemu 등 공부해보고 적용해볼 것들이 남았습니다
이후에 다른 프로젝트는 Jenkins+Docker Hub로 CI/CD를 구축해 볼 생각입니다
감사합니다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네이버 부스트캠프 웹·모바일 8기 합격 후기]]></title>
            <link>https://velog.io/@hyeonu_wrld/%EB%84%A4%EC%9D%B4%EB%B2%84-%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-%EC%9B%B9%EB%AA%A8%EB%B0%94%EC%9D%BC-8%EA%B8%B0-%ED%95%A9%EA%B2%A9-%ED%8C%81</link>
            <guid>https://velog.io/@hyeonu_wrld/%EB%84%A4%EC%9D%B4%EB%B2%84-%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-%EC%9B%B9%EB%AA%A8%EB%B0%94%EC%9D%BC-8%EA%B8%B0-%ED%95%A9%EA%B2%A9-%ED%8C%81</guid>
            <pubDate>Tue, 16 Apr 2024 10:50:44 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>마침 기술 블로그를 시작해야겠다고 마음 먹은 찰나에 네부캠 9기 모집 공고가 올라왔네요. 그래서 예전에 적어둔 회고를 보고 기억을 되살려 작년 8기 합격 후기겸 몇가지 팁들을 남겨보려합니다. 여기까지 찾아오신 분들이라면 네부캠에 지원하실 분들이실 것 같은데요. 저 또한 지원할 당시에 블로그들을 쥐 잡듯이 뒤져서 어떻게든 합격 정보를 알아내려했던 기억이 있어서 이후 기수에 지원하실 분들께 최대한 도움을 드리고 싶은 마음에 몇 자 적어봅니다. 다만, 코딩테스트 문제나 챌린지 과제들에 대한 상세한 내용은 유출을 할 수 없어 설명드리지 못하는 점 양해부탁드립니다.</p>
<h3 id="💭지원-동기">💭지원 동기</h3>
<p>우선 저는 컴퓨터공학과 전공자이지만, 특별한 기술 스택도 스펙도 없는 상황이었습니다. 당시 취업한 주변 친구들의 이야기를 들으면서 웹 개발에 흥미가 생겼지만 뭘 어디서부터 준비를 해야할 지 잘 모르겠어서 막연함을 갖고 학교를 다니고 있었습니다. 그러던 중 부트캠프에 관심을 갖게 되었고, 때마침 유명한 부트캠프 중 하나인 네이버 부스트캠프에서 8기 기수를 모집하는 것을 보고 지원하게 되었습니다.</p>
<h3 id="✍-자소서">✍ 자소서</h3>
<p>최대한 솔직하게 적었습니다.</p>
<p>저는 개인적으로 진행했던 프로젝트 경험도 전무했고, 웹 개발 프레임워크도 써본 적이 없었습니다. 그래서 사실 자소서를 쓸 때까지만 해도 제 실력으로는 부스트캠프에 들어가지 못할 것이라 판단했고, 설령 자소서에 과장된 내용을 적더라도 결국 들통날 거라 판단... 최대한 솔직하게 적는데에 초점을 맞췄습니다.</p>
<p>그래서 저는 제가 살아온 인생 경험을 위주로 적었고, 프로그래밍 관련으로는 학교에서 최근에 했던 팀프로젝트를 최대한 복기하며 상세히 적었습니다. 그리고 포트폴리오를 제출하는 항목에도 전공수업 팀프로젝트 발표 ppt를 첨부한게 전부였습니다. 스펙에 관해서 너무 주눅들지 않으셔도 될 것 같습니다!! 저 정말 포트폴리오라고 할게 없었거든요 ㅜ</p>
<p>사실 이래도 되나싶을 정도로 개인적인 이야기를 많이 녹여냈던 것 같은데, 이 부분이 어떻게 작용했는 지는 모르겠습니다. 다만 가벼운 마음으로 지원한게 아니라는 것만큼은 확실히 전달되었을 것 같습니다.</p>
<h3 id="💻-1차-코딩테스트">💻 1차 코딩테스트</h3>
<p><strong>유형 : 알고리즘 2문제 + cs 단답형 10문제
시간 : 120분
특이 사항 : 인터넷 검색 가능, 캠 필수, 생수만 취식 가능, 빈 a4용지로만 필기 가능</strong></p>
<p>자소서를 대충 적지만 않으면 1차 코딩테스트는 보게 해주는 것 같습니다. 그런데 하필 전공 기말시험과 1시간이 겹치는 바람에 둘 중에 하나를 포기해야했고, 결국 기말 시험을 30분 일찍 퇴장해서 코딩테스트를 봤네요ㅜ.. 그렇게 그 과목은 1점 차이로 a+을 놓치고 말았답니다 하핳</p>
<p>참고로 제 백준 티어는 골드1입니다. 그리고 코테를 따로 준비를 하지는 않았습니다! 기말고사와 겹치기도 했고 준비한다고 달라질 것 같지가 않아서 편한 마음으로 봤던 것 같습니다.</p>
<p>그리고 저는 바보같지만... 인터넷 검색 가능이란 사실을 몰랐습니다. 당연히 안될 거라 생각했는데 끝나고 오픈채팅방을 보니 다들 검색을 하셨더라구요 ㅠ 그래서 cs는 거의 전공자의 감으로 찍었습니다. 그래도 다행히 문제는 올솔을 했네요. 알고리즘 문제는 특별한 발상이 필요하기보다는(물론 발상이 좋으면 빠르게 풀 수도 있습니다) 구현능력이 필요했습니다.</p>
<p>인터넷 검색이 가능한지 꼭 확인하시고 응시하시길 바랍니다... 그리고 알고리즘 위주의 공부보다는 구현 위주로 공부하시면 좋을 것 같습니다. 알고리즘은 백준 실버 하위 수준의 기본적인 알고리즘만 익혀놔도 될 것 같습니다.</p>
<h3 id="💻-2차-코딩테스트">💻 2차 코딩테스트</h3>
<p><strong>유형 : 알고리즘 3문제 + 서술형 3문제
시간 : 150분
특이 사항 : 1차와 동일</strong>
1차와 동일하게 따로 준비하지는 않았고, 컨디션 관리에만 집중했습니다.</p>
<p>결론부터 말씀드리면 1솔합을 했습니다..!</p>
<p>저는 따로 준비를 안했기 때문에, 알고리즘보다는 시간이 오래 걸리는 구현 위주로 먼저 풀고자했고 1번이 적합해서 1번만 쭉 붙잡았습니다. 1번을 다푸는데 90분정도가 걸렸고, 이후엔 2번과 3번을 적당히 설계만 해둔채로 제출했습니다! 참고로, 2차 코딩테스트 결과로만 평가하는게 아닌 자소서 -&gt; 1차 -&gt; 2차로 이어진 선발과정 전반을 평가한다고 합니다. 개인적으로 1차/2차 모두 어떻게든 한문제라도 끝까지 구현했던게 도움이됐던 것 같습니다.</p>
<p>우선 서술형에 대해서 많이들 궁금해하실텐데 미리 알아서 특별히 도움이 될만한 수준의 문제는 아닙니다!! 문제 유출을 방지할 겸 따로 설명드리지는 않겠습니다. 알고리즘 문제를 풀었다면 자연스럽게 서술하실 수 있습니다 :) 그리고 앞서 말씀드린 것 처럼 알고리즘보다는 구현 위주입니다. 즉, 일부 백준 문제들처럼 복잡한 알고리즘을 알아야만 풀 수 있는 문제가 아닙니다!!</p>
<p>또한 챌린지를 마치고 보니 좀 새롭게 보이는게, 문제 요구사항대로 구현하는 과정 중에서 새로운 접근방법 or 예외 케이스 들을 발견하고 다시 수정해나가는 과정이 필요했는데 이 과정들이 챌린지 과제들과도 유사합니다. 결국 복잡한 문제를 해석하고 설계할 수 있어야하고 이어지는 버거운 구현 과정을 인내할 수 있어야할 것 같습니다.</p>
<p>그리고 너무 완벽한 설계에만 집착하지 마시고 일단 쉬운 접근방법이 떠오른다면 무작정 구현부터 해보시는 걸 추천합니다! 추가로 앞선 내용들에 도움이 되기 위해서는 언어 숙련도를 늘리시는게 필요할 것 같습니다. 구글링이 가능하다하지만, 구현 중에 함수 사용법을 검색할 정도로 시간이 남지는 않습니다.</p>
<h3 id="😱-챌린지">😱 챌린지</h3>
<p>챌린지에 관해서는 정말 할 말이 많지만, 상세하게 적자니 과제 유출의 우려도 있고.. 합격할 수 있을 지 고민하시는 후배 기수분들을 위한 팁을 위주로 가볍게 적어보겠습니다</p>
<p>우선 저는 정말 기본적인 html/css/js 지식만 있었습니다. nodejs를 사용해본적도 없다보니 js만으로 진행되는 과제들이 정말 막막했네요... 그래서 문법적인 애로사항을 마주쳤을 때 chatgpt를 적극 활용해 시간을 많이 절약할 수 있었습니다! 운영진분들도 ai를 어떻게 활용하는지 관심이 많으신지 챌린지 마지막에는 과제를 해결할 때 생성형 ai를 얼마나 이용했는 지 설문을 하시더라구요. 물론 과제들이 chatgpt에게 던져준다고 해결할 수 있을만큼 단순하지는 않았습니다. 과제의 실마리를 잡고 문법적인 도움을 받는 정도로 활용하시면 꽤나 도움이 됩니다 ㅎㅎ 그러니 js문법이 부족하다고 챌린지에 앞서 너무 걱정하시진 않으셔도 됩니다!</p>
<p>하지만 그럼에도 평일 평균 14<del>15시간 정도를 과제 해결에 투자했고, 주말에는 밀린 학습정리를 했습니다. 과제에 대해서도 간략히 말씀드리면, 저희 학교 기준으로 전공수업 때 한 두개 정도 나오는 정말 빡센 구현과제를 하루만에 구현하라는 정도의 볼륨입니다. 보통 학기 중에 2</del>3주는 기한으로 받는 과제를 매일매일 완성해야한다고 보시면 됩니다. 그러니 건강관리는 꼭 하세요 ㅠ 저도 챌린지 후반에 가니 허리 통증에 시달렸고, 다른 캠퍼분들도 손목 통증을 호소하시면서 팜레스트를 사시는 분들이 많았습니다.</p>
<p>제가 챌린지 외적으로 가장 걱정했던 부분은 역시 멤버십 합격 기준인데요! 이 글을 보시는 후배분들도 가장 걱정될 거라 생각합니다. 물론 매 기수마다 기준과 커트라인은 상이하겠으니 딱잘라 말씀드릴 순 없고, 제가 챌린지를 어떻게 진행했는 지 정리해볼테니 참고만 해주세요!</p>
<ol>
<li><p>출석
저는 체크인 체크아웃은 모두 제 시간에 했습니다. 한 번 늦잠을 자서 피어세션에 30분 지각했던 적이 있었습니다.</p>
</li>
<li><p>체크리스트
오후 7시까지 완성해야하는 체크리스트는 포기했습니다. 사실 나중엔 다들 새벽까지해서 완성하기 때문에, 1주차에 너무 7시라는 기준에 맞추지 않으셔도 됩니다. 하지만 늦더라도 모든 과제를 마무리하긴 했습니다! 주말에는 부족한 부분을 보충하기도 했습니다.</p>
</li>
<li><p>학습정리
학습정리도 사실 당일에 하도록 되어있지만, 저는 주말에 몰아서 했습니다. 다만 나중에라도 기억을 되짚어가며 정리를 할 수 있도록 구현 중간중간 캡쳐와 간단한 메모를 꾸준히 해두었던게 큰 도움이 됐습니다.</p>
</li>
<li><p>슬랙 참여도
이 부분에서 저는 고민이 많았는데요... 250명 가량이 참여하는 채널에서 뭔가 쉽게 질문을 올리고 이야기를 나누기가 극I인 저에게는 너무 어려웠습니다 ㅜㅜ 그래서 슬랙 참여도가 부족해서 떨어지지는 않을까?? 하는 생각이 들기도 했었어요.</p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/hyeonu_wrld/post/badd19f5-dd1b-40f8-b9c0-50328fcf0d69/image.png" alt=""></p>
<p>결과는 합격..!</p>
<p>요약하자면,  저는 미션 해결에 가장 집중했던 것 같습니다. 매일 밤을 새가면서 체크리스트를 어떻게든 채웠구요,,, 대신 학습 정리나 소통 측면에선 다소 부족했던 것 같아요 ㅜㅜ 반면에 미션을 다 못하더라도 학습과 정리에 더 시간을 투자하시는 분들도 정말 많았습니다 !!</p>
<p>결국엔 합격하신 분들의 공통점을 보면 어느 한쪽에 치우치지 않고 고루고루 열심히 하신 분들인 것 같아요. 너무 학습만 하느라 구현을 거의 못하거나, 구현만 하느라 학습을 놓치고 계시다면 주말에라도 시간을 내서 밸런스를 맞춰가는게 중요할 것 같습니다!! 그리고 슬랙 활동이 절대적인 기준은 아닌 것 같으니  너무 스트레스 받지는 않으셔도 될 것 같아요.</p>
<p>그리고 개인적으로는 정말 재밌었습니다 !! 과거 미화일수도 있긴한데,, 시간이 부족해서 몸이 힘들었다 뿐이지 이렇게 수백명의 개발자가 모여서 한가지 미션에 대해서 토론하고, 다양한 해결방식을 접하는 과정이 정말 재밌었습니다. 미션만으로도 재밌어서 아침부터 집중하다보면 끼니도 거르고 막 해가 지고있었고, 미션을 마무리하고나면 다음 날 아침에 캠퍼분들과 미션에 대해 얘기할 생각에 설레기도 했어요. (그렇다고 그때로 돌아가고 싶다는 건 아닙니다)</p>
<p><img src="https://velog.velcdn.com/images/hyeonu_wrld/post/f89af273-a393-40b6-af12-455db5f2b3f3/image.png" alt=""></p>
<p>챌린지 수료식을 마친 뒤,,</p>
<h3 id="🎉마치며">🎉마치며</h3>
<p>지원과정부터 멤버십 합격까지의 과정을 쭉 설명드렸는데, 도움이 좀 되셨으면 좋겠지만 적고보니 너무 모호한 것 같아 죄송하네요,, 그렇지만 적어도 저처럼 웹 개발 지식이 없더라도 열정만큼은 만땅인!! 사람도 충분히 합격할 수 있다는 걸 전해드리고 싶었습니다. 더 궁금한게 있으시면 댓글로 질문 남겨주시면 감사하겠습니다 ㅎㅎ</p>
]]></description>
        </item>
    </channel>
</rss>