KangMoo
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Docker ## Docker란? ![image](https://hackmd.io/_uploads/S1USx6EG0.png) Docker는 소프트웨어 개발 및 배포를 간소화하고 효율화하기 위한 플랫폼이다. 개발을 하다보면 다양한 환경에서 애플리케이션을 실행해야 하는 경우가 많다. 예를 들어, 개발자는 로컬 환경에서 애플리케이션을 개발하고, 테스트 환경에서 애플리케이션을 테스트하며, 프로덕션 환경에서 애플리케이션을 배포한다. 그런데, 실행 환경 간 불일치 문제로 인해 개발, 테스트, 배포 등의 과정에서 문제가 발생하는 경우가 많다. 즉, 개발 시에는 잘 작동하는 애플리케이션이 프로덕션 환경에서는 제대로 동작하지 않는 경우가 발생한다. ![image](https://hackmd.io/_uploads/H1aYU6NzC.png) 이러한 문제가 발생하는 이유는 각 환경마다 다른 라이브러리, 도구, 설정 등이 사용되기 때문이다. 따라서, 개발 환경과 프로덕션 환경을 일치시키는 것은 번거롭고 까다로운 작업이다. ![image](https://hackmd.io/_uploads/Hy1zc6VGA.png) 이러한 문제를 해결하기 위해 Docker는 컨테이너 기반의 가상화 기술을 사용하여 애플리케이션을 패키징하고 실행할 수 있는 환경을 제공한다. 컨테이너는 애플리케이션과 그 애플리케이션을 실행하는 데 필요한 모든 라이브러리, 도구 및 설정을 하나의 패키지로 묶은 가볍고 독립적인 실행 환경이다. Docker는 이러한 컨테이너를 관리하고 실행할 수 있는 도구와 서비스를 제공한다. 다만 이런 문제는 과거에도 이미 존재했던 문제이며, 이를 해결하기 위해 가상화 기술이 사용되었다. 그러나 가상화 기술은 가상 머신을 생성하고 운영체제를 설치하는 등의 과정이 필요했기 때문에 무겁고 느렸다. 반면 Docker는 컨테이너를 사용하여 가상화의 부담을 최소화하고 성능을 최적화하였다. 따라서 Docker는 가상화 기술의 단점을 보완하고, 더욱 경량하고 이식성이 높은 환경을 제공한다. ![image](https://hackmd.io/_uploads/By604uyMR.png) 즉, 도커는 빠른 실행이 가능한 가상 환경을 제공하며, 이를 통해 개발, 테스트, 배포 등의 과정을 효율적으로 관리할 수 있게 해준다. ## Docker의 주요 특징 1. **경량성** : 컨테이너 기반의 Docker는 가상화의 부담을 최소화하고 성능을 최적화한다. 2. **이식성** : Docker는 어떠한 환경에서도 동일하게 작동하며, 코드의 이식성을 증가시킨다. 3. **모듈성** : Docker는 애플리케이션을 작은 조각으로 나누어 관리하므로, 각 부분을 독립적으로 개발하고 업데이트 할 수 있다. ## Docker 설치하기 Docker를 시작하기 위해서는 먼저 시스템에 Docker를 설치해야 한다. ### Windows에서 Docker 설치하기 Windows 10에서는 Docker Desktop을 사용하여 Docker를 설치할 수 있다. 1. Docker Desktop을 다운로드하기 위해 Docker 허브 [Docker Hub](https://hub.docker.com/editions/community/docker-ce-desktop-windows/) 페이지에 접속한다. 2. 'Get Docker' 버튼을 클릭하여 Docker Desktop 설치 파일을 다운로드한다. 3. 다운로드 받은 실행 파일을 실행하면 설치가 시작된다. > [공식 설치 문서](https://docs.docker.com/desktop/install/windows-install/) ### MacOS에서 Docker 설치하기 MacOS에서는 Docker Desktop for Mac을 사용하여 Docker를 설치할 수 있다. 1. Docker Desktop for Mac을 다운로드하기 위해 Docker 허브 [Docker Hub](https://hub.docker.com/editions/community/docker-ce-desktop-mac/) 페이지에 접속한다. 2. 'Get Docker' 버튼을 클릭하여 Docker Desktop 설치 파일을 다운로드한다. 3. 다운로드 받은 '.dmg' 파일을 열고 'Docker.app'을 Applications 폴더로 드래그한다. > [공식 설치 문서](https://docs.docker.com/desktop/install/mac-install/) ### Linux에서 Docker 설치하기 Linux에서는 패키지 매니저를 이용하여 Docker를 설치할 수 있다. Ubuntu를 기준으로 설명하면 다음과 같다. 1. 터미널을 열고 `sudo apt-get update` 명령어를 입력하여 패키지 리스트를 업데이트한다. 2. `sudo apt-get install docker-ce` 명령어를 입력하여 Docker를 설치한다. 3. 설치가 완료되면 `docker --version` 명령어를 입력하여 정상적으로 설치되었는지 확인한다. > [공식 설치 문서](https://docs.docker.com/desktop/install/linux-install/) ## Docker의 이미지와 컨테이너 이해하기 Docker를 이해하는 데 있어 가장 중요한 개념 중 두 가지는 바로 '이미지'와 '컨테이너'다. 두 개념을 이해하면 Docker의 전반적인 동작 방식을 더 잘 이해할 수 있다. ### Docker 이미지 Docker 이미지는 애플리케이션을 실행하는 데 필요한 모든 것을 포함하고 있는 불변(immutable)의 파일 시스템이다. 이는 실행 가능한 소프트웨어 코드, 사용되는 라이브러리, 도구, 환경 변수 및 설정 파일 등을 포함한다. 이미지는 컨테이너를 생성하기 위한 '템플릿'으로 생각할 수 있다. 한 이미지에서 여러 개의 컨테이너를 생성할 수 있으며, 각각의 컨테이너는 독립적으로 작동한다. Docker 이미지는 Docker Hub와 같은 Docker 레지스트리에 저장되고 공유될 수 있다. `docker pull` 명령을 사용하면 이러한 레지스트리에서 이미지를 다운로드할 수 있다. ### Docker 컨테이너 Docker 컨테이너는 Docker 이미지를 기반으로 생성되며, 이미지의 실행 가능한 인스턴스다. 컨테이너는 이미지의 실행 버전이며, 독립적인 파일 시스템과 네트워크 인터페이스, 프로세스 공간을 가지고 있다. `docker run` 명령을 사용하면 이미지에서 컨테이너를 실행할 수 있다. 실행 중인 컨테이너는 `docker ps` 명령을 통해 확인할 수 있다. 결론적으로, Docker 이미지는 애플리케이션과 그 실행 환경을 묶은 것이며, Docker 컨테이너는 이 이미지를 실행한 상태라고 생각하면 된다. 이렇게 함으로써 개발, 테스팅, 배포 과정에서 일관된 환경을 보장할 수 있다. > 아주 따라서 극단적으로 단순화하자면, 이미지는 일종의 '프로그램'이며, 컨테이너는 이 이미지를 실행한 '프로세스'라고 생각할 수 있다. ## Docker 기본 명령어 Docker를 설치한 후에는 Docker 명령어를 사용하여 다양한 작업을 수행할 수 있다. 여기서는 Docker의 기본 명령어에 대해 알아본다. ### Docker 버전 확인 ```bash docker --version ``` 이 명령어를 입력하면 Docker의 버전 정보가 표시된다. 만약 Docker가 설치되어 있지 않다면, 먼저 Docker를 설치해야 한다. ### Docker 이미지 목록 확인 ```bash docker images ``` 이 명령어를 사용하면 현재 로컬에 저장된 Docker 이미지의 목록을 확인할 수 있다. ### Docker 이미지 다운로드 Docker 이미지를 다운로드하려면 `docker pull` 명령어를 사용한다. 예를 들어, Ubuntu 이미지를 다운로드하려면 아래와 같이 입력한다. ```bash docker pull ubuntu ``` 이 이미지는 Docker Hub에서 제공되며, Docker의 공식 이미지 저장소인 Docker Hub에는 다양한 운영체제 및 소프트웨어 이미지가 저장되어 있다. > Docker Hub는 Docker의 공식 이미지 저장소로, 다양한 운영체제 및 소프트웨어 이미지를 제공한다. DockerHub에서는 사용자가 직접 이미지를 업로드하고 공유할 수도 있다. (앱스토어와 비슷한 개념) ### Docker 이미지 삭제 Docker 이미지를 삭제하려면 `docker rmi` 명령어를 사용한다. 예를 들어, 이미지 ID가 `[ImageName]`인 이미지를 삭제하려면 아래와 같이 입력한다. ```bash docker rmi [ImageName] ``` ### Docker 컨테이너 실행 Docker 컨테이너를 실행하려면 `docker run` 명령어를 사용한다. 예를 들어, Ubuntu 컨테이너를 실행하려면 아래와 같이 입력한다. ```bash docker run -it ubuntu ``` 여기서 `-it` 옵션은 인터랙티브 모드로 터미널을 사용할 수 있도록 해준다. 위 명령어를 실행하면 Ubuntu 컨테이너 내부로 들어가게 된다. 컨테이너 내부에서 `exit` 명령어를 입력하면 컨테이너를 종료하고 나오게 된다. > run 실행 시 이미지가 없으면 자동으로 pull을 시도한다. ### 포트 포워딩을 사용한 Docker 컨테이너 실행 Docker 컨테이너를 실행할 때 포트 포워딩을 사용하려면 `-p` 옵션을 사용한다. 예를 들어, Nginx 컨테이너를 실행하고 호스트의 포트 80을 컨테이너의 포트 80에 매핑하려면 아래와 같이 입력한다. ```bash docker run -p 80:80 nginx ``` 위 명령어를 실행하면 Nginx 웹 서버가 실행되고, 웹 브라우저에서 `http://localhost`로 접속하면 Nginx의 기본 페이지를 확인할 수 있다. ### 백그라운드에서 Docker 컨테이너 실행 컨테이너를 백그라운드에서 실행하려면 `-d` 옵션을 사용한다. 예를 들어, Nginx 컨테이너를 백그라운드에서 실행하려면 아래와 같이 입력한다. ```bash docker run -d -p 80:80 nginx ``` ### 실행중인 Docker 컨테이너에 접속 만약 백그라운드에서 실행 중인 Docker 컨테이너에 접속하려면 `docker exec` 명령어를 사용한다. 예를 들어, 컨테이너 ID가 `[ContainerName]`인 컨테이너에 접속하려면 아래와 같이 입력한다. ```bash docker exec -it [ContainerName] /bin/bash ``` > `-i` : interactive 모드. 표준 입력을 통해 컨테이너에 입력할 수 있도록 함 > `-t` : tty를 할당. 쉘을 사용할 수 있도록 함 ### Docker 컨테이너 목록 확인 실행 중인 Docker 컨테이너의 목록을 확인하려면 `docker ps` 명령어를 사용한다. ```bash docker ps ``` ### Docker 컨테이너 중지 실행 중인 Docker 컨테이너를 중지하려면 `docker stop` 명령어를 사용한다. 예를 들어, 컨테이너 ID가 `[ContainerName]`인 컨테이너를 중지하려면 아래와 같이 입력한다. ```bash docker stop [ContainerName] ``` ### Docker 모든 컨테이너 확인 Docker 컨테이너는 중지되었다고 바로 삭제되지 않는다. 왜냐하면 중지된 컨테이너는 언제든 다시 시작할 수 있기 때문이다. 그런데 중지된 컨테이너는 `docker ps` 명령어로 확인할 수 없다. `docker ps` 명령어는 '실행 중인' Docker 컨테이너의 목록만을 확인하기 때문이다. 따라서 중지된 컨테이너는 확인되지 않는다. 중지된 컨테이너를 포함하여 모든 Docker 컨테이너의 목록을 확인하려면 `-a` 옵션을 사용한다. ```bash docker ps -a ``` ### Docker 컨테이너 삭제 컨테이너를 중지해도 Docker 컨테이너는 삭제되지 않는다. '중지' 했을 뿐 언제든 다시 시작할 수 있다. 컨테이너를 삭제하려면 `docker rm` 명령어를 사용한다. 예를 들어, 컨테이너 ID가 `[ContainerName]`인 컨테이너를 삭제하려면 아래와 같이 입력한다. 중지된 Docker 컨테이너를 삭제하려면 `docker rm` 명령어를 사용한다. 예를 들어, 컨테이너 ID가 `[ContainerName]`인 컨테이너를 삭제하려면 아래와 같이 입력한다. ```bash docker rm [ContainerName] ``` #### 실행중인 Docker 컨테이너에 접속 시 주의사항 실행중인 컨테이너에 접속중인 상태에서 빠져나올 때, `exit` 명령어를 사용하면 컨테이너가 종료된다. 컨테이너의 쉘에서 작업 중에 일시적으로 쉘을 빠져나가고 싶다면 `Ctrl + P`, `Ctrl + Q` 키 조합을 이용한다. 이 키 조합을 사용하면 현재 실행 중인 컨테이너를 종료하지 않고 쉘에서 빠져나올 수 있다. > Docker의 쉘에서 `exit` 혹은 `Ctrl + D`를 사용하면, 현재 실행 중인 프로세스(여기서는 쉘)가 종료되는데, 이 때 Docker는 해당 프로세스가 종료되었음을 감지하고 컨테이너를 종료시킨다. 이를 통해 컨테이너 내의 주요 프로세스가 실패하면 자동으로 컨테이너를 정리하도록 설계되어 있다. 이러한 동작은 "PID 1 문제"라고 불리우는데, UNIX와 Linux 시스템에서 PID 1은 시스템 종료 시까지 계속 실행되며, 모든 자식 프로세스의 종료를 처리한다. 컨테이너에서 실행하는 프로세스는 PID 1로 실행되며, 이 프로세스가 종료되면 컨테이너도 함께 종료된다. > > 반면에, `Ctrl + P`, `Ctrl + Q` 조합을 사용하면 쉘에서 빠져나오게 되지만, Docker 컨테이너는 여전히 실행 중이다. 이는 Docker의 'detach' 모드로, 컨테이너를 백그라운드에서 계속 실행하면서도 쉘에 접근하거나 컨테이너에서 벗어날 수 있게 해준다. 이렇게 하면 여러 컨테이너를 동시에 관리하거나, 백그라운드 작업을 수행하면서도 다른 작업을 계속할 수 있다. 이런 동작은 'detaching'이라고 부른다. > > 따라서, 컨테이너 내부에서 작업을 한 뒤 `Ctrl + P`, `Ctrl + Q`를 사용하여 detaching하면, 작업은 계속 실행되지만 사용자는 다른 명령어를 입력하거나 다른 컨테이너로 전환할 수 있다. ## Docker 파일시스템 설정 Docker 컨테이너는 격리된 파일시스템을 사용한다. 이는 각 컨테이너가 독립적으로 운영될 수 있도록 하며, 컨테이너 간의 간섭을 최소화한다. Docker의 파일시스템 설정은 크게 두 가지로 나뉜다. 볼륨(Volumes)과 바인드 마운트(Bind Mounts)가 있다. ## Docker 볼륨(Volumes) Docker 볼륨은 컨테이너가 사용하는 데이터를 호스트와 공유하거나, 컨테이너 간에 데이터를 공유하는 데 사용된다. 볼륨을 사용하면 컨테이너가 종료되어도 데이터가 유지되며, 여러 컨테이너 간에 데이터를 공유할 수 있다. ### Docker 볼륨 생성 Docker 볼륨을 생성하려면 `docker volume create` 명령어를 사용한다. 예를 들어, `my-volume`이라는 이름의 볼륨을 생성하려면 아래와 같이 입력한다. ```bash docker volume create my-volume ``` ### Docker 볼륨 목록 확인 Docker 볼륨의 목록을 확인하려면 `docker volume ls` 명령어를 사용한다. ```bash docker volume ls ``` ### Docker 볼륨 삭제 Docker 볼륨을 삭제하려면 `docker volume rm` 명령어를 사용한다. 예를 들어, `my-volume`이라는 이름의 볼륨을 삭제하려면 아래와 같이 입력한다. ```bash docker volume rm my-volume ``` ### Docker 볼륨을 사용하여 컨테이너 실행 Docker 볼륨을 사용하여 컨테이너를 실행하려면 `-v` 옵션을 사용한다. 예를 들어, `my-volume`이라는 이름의 볼륨을 사용하여 Ubuntu 컨테이너를 실행하려면 아래와 같이 입력한다. ```bash docker run -v my-volume:/app -it ubuntu ``` 위 명령어를 실행하면 `my-volume`이라는 이름의 볼륨을 `/app` 디렉토리에 마운트한 Ubuntu 컨테이너가 실행된다. 컨테이너에 접속하여 `/app` 디렉토리에 파일을 생성하면, 해당 파일은 호스트의 `my-volume` 볼륨에 저장된다. 따라서, 컨테이너가 종료되어도 데이터는 유지된다. ### Docker 볼륨을 사용하여 컨테이너 간 데이터 공유 Docker 볼륨을 사용하면 컨테이너 간에 데이터를 공유할 수 있다. 예를 들어, `my-volume`이라는 이름의 볼륨을 사용하여 Ubuntu 컨테이너를 실행하고, 해당 볼륨을 사용하여 Nginx 컨테이너를 실행하려면 아래와 같이 입력한다. ```bash docker run -v my-volume:/app -it ubuntu docker run -v my-volume:/usr/share/nginx/html -p 80:80 nginx ``` 위 명령어를 실행하면 `my-volume`이라는 이름의 볼륨을 `/app` 디렉토리에 마운트한 Ubuntu 컨테이너와 `/usr/share/nginx/html` 디렉토리에 마운트한 Nginx 컨테이너가 실행된다. ### 바인드 마운트(Bind Mounts) 바인드 마운트는 호스트 파일 시스템의 특정 디렉토리를 컨테이너 내부의 특정 경로에 연결하는 방식이다. 바인드 마운트는 호스트 시스템의 디렉토리를 그대로 사용하기 때문에 컨테이너가 종료되더라도 데이터가 그대로 유지된다. #### 바인드 마운트 사용 예제 ```shell docker run -d -v /host/data:/container/data --name my_container ubuntu ``` 위 명령어는 호스트의 `/host/data` 디렉토리를 컨테이너의 `/container/data` 경로에 마운트하여 `ubuntu` 이미지를 기반으로 `my_container`를 실행한다. ## Docker 명령어 정리 Docker를 사용할 때 자주 사용되는 명령어를 정리하면 다음과 같다. ```shell docker ├── login : Docker에 로그인 ├── version : Docker의 버전 확인 ├── images : 사용 가능한 Docker 이미지 리스트 확인 ├── image │ ├── ls : 사용 가능한 Docker 이미지 리스트 확인 │ ├── pull [ImageName] : Docker Hub 또는 다른 저장소로부터 이미지 가져오기 │ ├── push [ImageName] : Docker Hub 또는 다른 저장소로 이미지 업로드 │ ├── build -t [RepositoryName] [Directory] : Dockerfile을 사용하여 이미지 생성 │ └── rm [ImageName] : 이미지 삭제 ├── rmi [ImageName] : 이미지 삭제 ├── ps : 실행 중인 컨테이너 리스트 확인 │ ├── -a : 모든 컨테이너 리스트 확인 │ └── -q : 모든 컨테이너 ID 확인 ├── container │ ├── ls : 실행 중인 컨테이너 리스트 확인 │ ├── restart [ContainerID] : 컨테이너 재시작 │ ├── rm [ContainerID] : 컨테이너 삭제 (정지 상태 필요) │ └── prune : 정지된 모든 컨테이너 삭제 ├── exec -it [ContainerID] │ ├── [Command] : 실행 중인 컨테이너에서 명령 실행 │ ├── /bin/bash : 컨테이너에 접근하여 Bash 쉘 실행 │ └── sh : 컨테이너에 접근하여 Bourne 쉘 실행 ├── run [ImageName] │ ├── --name [Name] : 이름 지정하여 컨테이너 생성 및 실행 │ ├── -p [HostPort]:[ContainerPort] : 포트 연결하여 컨테이너 실행 │ ├── -d : 백그라운드에서 컨테이너 실행 │ └── -v [HostPath]:[ContainerPath] : 호스트와 컨테이너 경로 연결(마운트) ├── volume │ ├── create [VolumeName] : 볼륨 생성 │ ├── ls : 볼륨 리스트 확인 │ ├── rm [VolumeName] : 볼륨 삭제 │ └── prune : 모든 볼륨 삭제 ├── stop [ContainerID] : 실행중인 컨테이너 종료 ├── start [ContainerID] : 종료된 컨테이너 실행 ├── tag [ImgName]:[Tag] [ImgName]:[NewTag] : 이미지 태그 변경 ├── logs [ContainerName] : 컨테이너 로그 확인 └── inspect [ContainerName] : 컨테이너 상세 정보 확인 ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully