tk3c-mpos
      • 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
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners 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
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
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
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners 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
    1
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- tags: mPOS --- <!-- <style> hr{ page-break-after: always } </style> --> # MPOS安裝 [toc] ## 總部安裝 :::danger - 新增的門市IP需重新寫進CA([參考](#3-更新SSL憑證)) - CA更新後須重啟tomcat ::: ### RPI #### **Prerequisite** - Peripherals - 有HDMI 螢幕 - USB鍵盤/滑鼠 > :::info > 先接上周邊再開機 > ::: - 連接內網 - Wifi設定 - 修改 `/etc/wpa_supplicant/wpa_supplicant.conf` (需 root 權限) ``` ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 country=TW # SET wifi conn network={ ssid="..." key_mgmt="..." wep_key0="..." #如使用AP-PDA注意密碼前後沒有雙引號" #disabled=1 } ``` - 執行 `sudo wpa_cli -i wlan0 reconfigure` - 執行 `ip addr` 確認連上 #### 1. 確認系統更新 ([若無需更新跳至 2.](#2-%E7%A2%BA%E8%AA%8D%E7%A8%8B%E5%BC%8F%E6%9B%B4%E6%96%B0)) 1. ssh tunnel to RPi ```bash ssh -R 1080 tk3c@<rpi-ip> ``` 2. 確認系統 日期/時間 正確 - 在總部無法連ntp, 需手動更新時間, 確認10.1.62.97 API 正常運作 並執行 ```bash /opt/tk3c/bin/pos-calibratetime.sh ``` 4. 更新系統 :::warning 系統時間不正確 會 **更新失敗** ::: **Choose 1 of 2 of the following methods** 1. 如果 `/etc/apt/apt.conf.d/12proxy` **有設定** `Acquire::http::Proxy "socks5h//localhost:1080"`, ``` > $ cat /etc/apt/apt.conf.d/12proxy > Acquire::http::Proxy "socks5h://localhost:1080"; ``` 可執行 ```bash sudo apt update && sudo apt full-upgrade -y sudo apt autoremove ``` 2. 如果 **沒有設定**`/etc/apt/apt.conf.d/12proxy`, 可執行 ```bash sudo proxychains apt update && sudo apt full-upgrade -y sudo proxychains apt autoremove ``` :::warning - 如果 沒有安裝 `proxychains` 1. 設定 apt socks5 proxy ```bash echo 'Acquire::http::Proxy "socks5h//localhost:1080";' | sudo tee -a /etc/apt/apt.conf.d/12proxy ``` 2. 安裝 proxychains ```bash sudo apt update && sudo apt full-upgrade -y sudo apt install -y proxychains sudo apt autoremove ``` 3. 在 `/etc/proxychains.conf` 之 `[ProxyList]` section 加上 `socks5 127.0.0.1 1080` ```cfg [ProxyList] # add proxy here ... socks5 127.0.0.1 1080 ``` ::: :::info - 如果 要使用 `proxychains` 執行 `apt`, 需移除 `/etc/apt/apt.conf.d/12proxy` 的 proxy 設定 ::: #### 2. 確認程式更新 **確認所有 程式/角本 已更新至最新穩定版本** - API - `curl localhost:8080/mPOS/status` 確認版本 - Choose 1 of the following method for updating API - From 97 - Manually 1. Run `/home/tk3c/build_mpos` > build 成功時會自動上傳至IDC:`/opt/tk3c/staging/war` 3. rsync 新建置 war 至 `tk3c@<rpi>:/opt/tk3c/staging/war` ```bash rsync -avzh /opt/tk3c/staging/war/<war_file> tk3c@<rpi>:/opt/tk3c/staging/war/ ``` 3. 執行 ```bash ssh tk3c@<rpi> '/opt/tk3c/bin/pos-deployapi.sh mPOS /opt/tk3c/staging/war/<war_file>' ``` - `mpos_tool.py` 1. (Optional) Run `/home/tk3c/build_mpos` 2. 更新 deployment_version.ini 3. Run ```bash python3 mpos_tool.py deploy --only <RPi ip> ``` - From development devices - 從IDC上取得最後建置WAR檔 1. 至 https://10.254.248.41/builds/backend/api/ 選擇要部屬的war 2. 下載檔案並scp或rsync至`tk3c@<rpi>:/opt/tk3c/staging/war` 3. 執行 ```bash ssh tk3c@<rpi> '/opt/tk3c/bin/pos-deployapi.sh mPOS /opt/tk3c/staging/war/<war_file>' ``` - 自行執行 gradle 建置 war > - 取得 原始碼 `git clone http://172.16.9.53:80/IT_MPOS/mPOS.git` > - (optional) 切至 backend 分支 `git checkout backend` 1. 至 mPOS/Backend/mPOS 執行 gradle script ```cmd > .../mPOS/BackEnd/mPOS/gradlew.bat --debug -x test -S --info build -Premoterepo ``` 2. scp或rsync `mPOS/Backend/mPOS/build/libs/mPOS_<...>.war` 至`tk3c@<rpi>:/opt/tk3c/staging/war` 3. ssh 執行 `tk3c@<rpi>:/opt/tk3c/bin/pos-deployapi.sh` ```bash /opt/tk3c/bin/pos-deployapi.sh mPOS /opt/tk3c/staging/war/<war_file> ``` - From RPi - 從IDC上rsync最後建置WAR檔 1. 從 rsync 要部屬的war ```bash rsync -avzh tk3c@10.254.248.41:/opt/tk3c/staging/war/<war_file> /opt/tk3c/staging/war/ ``` 2. 執行 `/opt/tk3c/bin/pos-deployapi.sh mPOS <war_file>` - `/opt/tk3c/bin` 所有檔案 - python 與 shell script 檔直接覆蓋 ([source code](http://172.16.9.53/IT_MPOS/mPOS/src/branch/master/BackEnd/scops/mpos_oss)) > 可以從 IDC 取得所有檔案, 印表機設定檔除外 > > rsync -avzh tk3c@10.254.248.41:/opt/tk3c/staging/oss/bin/ /opt/tk3c/bin/ --exclude=tk3c_posprint.json - `/opt/tk3c/services` 所有systemd service ([source files](http://172.16.9.53/IT_MPOS/mPOS/src/branch/master/BackEnd/scops/mpos_oss/services/tk3c)) > 可以從 IDC 取得所有檔案 > > rsync -avzh tk3c@10.254.248.41:/opt/tk3c/staging/oss/services/ /opt/tk3c/services/ - 如果有更新, 更新後執行 `sudo systemctl daemon-reload` #### 3. 更新SSL憑證 - openssl 指令: 自簽憑證/重簽憑證 參 [notes: self_signed_certificates.md](http://172.16.9.53/IT_MPOS/mPOS/src/branch/master/BackEnd/scops/notes/self_signed_certificates.md) - 使用resign_certs.sh重簽憑證 (參 [certs](http://172.16.9.53/IT_MPOS/mPOS/src/branch/master/BackEnd/scops/certs)) ``` <mpos repo>/BackEnd/scops/certs/resign_certs.sh ``` - 只需把更新後的憑證 **`tk3c_mpos_server.crt`** 發布至 部屬之RPi+IDC: `/opt/tk3c/ssl` <hr/> #### SD Card Clone ##### Method 1: **SD Card Copier** (Recommended) ![](https://i.imgur.com/4q4r4j8.jpg) or ##### Method 2: **`dd`** command ```bash sudo dd bs=4M if=/dev/mmcblk0 of=/dev/sda status=progress ``` > [reference: backup](https://www.raspberrypi.org/documentation/linux/filesystem/backup.md) #### 設定檔 ##### 更改 - `/etc/hosts` ```php 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 mposapi ######## SET SCDB IP ########## # 10.2.219.250 scdb.mpos.local 10.253.2.250 scdb.mpos.local ``` - `/etc/dhcpcd.conf` ```php ... # SET STATIC IP interface eth0 static ip_address=10.*.*.245/24 static routers=10.*.*.254 static domain_name_servers=10.1.1.249 10.1.1.242 ... ``` - `/opt/tk3c/bin/store_env` - 參考`/opt/tk3c/bin/store_env.sample`編輯`/opt/tk3c/bin/store_env`, 視需要修改store no, 若有多數server部署同一門市再修改scope id ```python export tk3c_store_no=705 # CHANGE STORE NO #export tk3c_scope_id=lab export tk3c_home=/opt/tk3c # modify following for TomEE's environment export TK3CLIB="/opt/tomcat/tk3c-lib" export sc_storeno="$tk3c_store_no" export sc_mqtt_broker="tcp://localhost:1883" export tk_api_header_key="X-Powered-TK" export tk_api_header_value="..." export tk_api_url="http://10.254.249.12:18718" export wish_api_url="http://10.254.248.21:8765" export pr_api_url="http://172.16.9.188" export pr_api_clientid="..." export pr_api_pwd="..." ``` - ~~`/opt/tk3c/bin/tk3c-posprint.json`~~ (Old) (20210928 All store rpi updated, use `tk3c-posprint.ini`) :::spoiler - change IP (endpoint) ```json { "printers":[ {"id":"0", "enable":true, "name":"PRN0", "type":"Dummy", "vendor":null, "model":"RP700", "endpoint":null}, {"id":"1", "enable":false, "name":"PRN1", "type":"Network", "vendor":"Epson", "model":"T70II", "endpoint":"192.168.192.168"}, {"id":"2", "enable":true, "name":"PRN2", "type":"Network", "vendor":"Partner", "model":"RP700", "endpoint":"192.168.1.251"} ], "settings":{...}, "reserved_usb":[...] } ``` ::: - `/opt/tk3c/bin/tk3c-posprint.ini` (Current) - change printer IP ```cfg [DEFAULT] broker=localhost:1883 topic=tk3c/{id}/prn/+ topic_reply=tk3c/{id}/prnjob/{sn} topic_status=tk3c/{id}/prns topic_will=tk3c/{id}/prnwill spec_key=Dt8lyToo17X/XkXaQvihuA== key=9FA6908E5DAFF6CBBCEB4CFCFDB11487 title=燦坤3C logo=/opt/tk3c/bin/tk3clogo.bmp disclaimer_einvoice= 更正內容請於開立日起五日內持電子 發票證明聯辦理,逾期恕不受理; 商品退換時請持電子發票證明聯及 銷貨明細辦理 disclaimer_receipt= 1.本單據不得作為兌獎之憑證。 2.更正內容請於開立日起五日內憑本單據辦理,逾期恕不受理。 disclaimer_donate= 提醒您,捐贈發票不得辦理兌領獎 disclaimer_deliver= (販賣約定條款) 凡客訂商品,買受人同意支付一定比例之訂金(實際訂金之金額,應依本公司規定為準),若因可歸責於"買受人"/"指定第三人"因素(例買受人留存資訊不實無法配送,經通知仍不取貨),致60日內未完成交易者,買受人同意燦坤依民法規定,沒收全部訂金並解除本買賣契約(經燦坤依販賣明細單地址發函通知取貨人時,即生解除契約效力) (安裝提醒) 除加購或贈送之「標準安裝」外,現場有「非標準安裝」之需求者,另以「工程確認書」報價收費,尤其「空調一對多系列」無贈送安裝,需額外報價收費 footer= Thanks for your shopping please come again [0] enable=1 name=PRN0 type=Dummy model=RP700 vendor=None [1] enable=0 name=PRN1 type=Network vendor=Epson model=T70II ip=192.168.192.168 [2] enable=1 name=PRN2 type=Network vendor=Partner model=RP700 ip=192.168.1.251 # update IP(各門市printer ip) e.g. ip=10.2.219.241 vid=0x076c pid=0x0302 iep=0x85 oep=2 ``` - `/etc/mosquitto/conf.d/tk3c.conf` - 編輯 mosquitto 設定檔, 視需要修改 bridge connection與topic中之store no ```python # bridge settings # connection bg219 #SET STORE NO connection bg705 address 10.254.248.41:1883 # topic tk3c/log/+/219 out 0 #SET STORE NO topic tk3c/log/+/705 out 0 topic tk3c/mpos/+ in 0 ``` :::info 變更後視狀況 重啟服務 ```bash sudo systemctl restart mosquitto.service ``` ::: ##### 檢查 - `/etc/nginx/conf.d/tk3c.conf` or ~~`/etc/nginx/sites-enabled/default`~~(20210928 removed) ```conf upstream tomcat { server 127.0.0.1:8080 weight=100 max_fails=5 fail_timeout=5; } server { listen 80; listen [::]:80; listen 443 default_server ssl; listen [::]:443 default_server ssl; include snippets/ssl-params.conf; ssl_certificate /opt/tk3c/ssl/mpos_server.crt; ssl_certificate_key /opt/tk3c/ssl/mpos_server.key; server_name _; charset UTF-8; root /var/www/html; index index.html index.nginx-debian.html; location / { try_files $uri $uri/ =404; } location /mPOS/ { proxy_pass http://tomcat/mPOS/; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_hide_header 'X-Frame-Options'; add_header X-Frame-Options ALLOWALL; } location /logs/ { if ($scheme = 'http') { rewrite ^ https://$http_host$request_uri? permanent; } sendfile on; sendfile_max_chunk 1m; alias /opt/tk3c/logs/; autoindex on; autoindex_localtime on; add_header Access-Control-Allow-Origin *; default_type text/plain; } } ``` - `/etc/network/interfaces.d/eth0-subs` check ip alias same subnet as receipt printer's default ip range (192.168.1.xxx) ``` auto eth0:1 allow-hotplug eth0:1 iface eth0:1 inet static vlan-raw-device eth0 address 192.168.1.245 netmask 255.255.255.0 ``` - `/etc/wpa_supplicant/wpa_supplicant.conf` - remove auto connect wifi APs ``` ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 country=TW # DELETE OR COMMENT OUT CONNECTION SETTING #network={ #ssid="AP-PDA" #key_mgmt=NONE #wep_key0= #} # OR SET disabled=1 TO PREVENT AUTOMATIC CONNECTION ON BOOT network={ ssid="..." key_mgmt="..." wep_key0="..." disabled=1 } ``` #### Final check Run `/opt/tk3c/bin/check_env.sh` to check overall setting summary ### RP-700 Receipt Printer - 進入Printer設定頁面(192.168.1.251) - 點選configure interface - 預設帳號/密碼: admin/不輸入 - 更改ip address - Fixed ip address - device ip address(xxx.xxx.xxx.241) - gateway address(xxx.xxx.xxx.254) - 重啟印表機 - 確認印表機IP 成功更改 - ping xxx.xxx.xxx.241 or - 可以順利進入Printer設定頁面(xxx.xxx.xxx.241) - 測試列印 `/opt/tk3c/bin/test_print_receipt.sh` ::: success - 印表機程式重啟 sudo systemctl restart pos-print ::: <hr/> ### Mobile device [參考文件](https://10.254.248.41/tk3c/) * 憑證 + 憑證安裝 已改由MDM統一推送 + 憑證確認 由以下步驟確認憑證已安裝且啟用 ![CA1](https://i.imgur.com/uAklv7z.png) ![CA2](https://i.imgur.com/VXzglum.png) ![CA3](https://i.imgur.com/4qUO3k4.png) * 裝置管理設定 [管理後台](https://10.254.248.41/tk3c/admin/) device設定步驟 ![reg_step01](https://i.imgur.com/jnc0Ezt.png) ![reg_step02](https://i.imgur.com/1tJ3UBx.png) 只需設定Device sn、deployment Device sn 使用 IPAD sn deployment 設定參考: ```javascript { "api":"10.1.62.97", //rpi ip "termNo":"0025", // POS機號 "storeNo":"705", // 店號 "broker":"" // MQTT Broker uri目前不需設定 } ``` ![reg_step03](https://i.imgur.com/pJl05Pr.png) * MPOS安裝 + 開啟安裝頁面 <https://10.254.248.41/tk3c/mdm> ![PWA1](https://i.imgur.com/AWCNg4C.png) ![PWA2](https://i.imgur.com/x5Xa6wo.jpg) ![PWA3](https://i.imgur.com/4yGMTYu.png) ![PWA4](https://i.imgur.com/I75SFCO.png) ![PWA5](https://i.imgur.com/9TionmS.png) ![PWA6](https://i.imgur.com/fbqwlWT.jpg) * [掃描器配對](https://hackmd.io/SIA4rdAjQ_GntkYL2aO12w?view#%E6%A2%9D%E7%A2%BC%E6%8E%83%E6%8F%8F%E5%99%A8) --- ## [門市安裝](https://hackmd.io/SIA4rdAjQ_GntkYL2aO12w) ## 問題排除 ### 門市連線 示範軟體[mobaxterm](https://mobaxterm.mobatek.net/) * add new session ![](https://i.imgur.com/f39Mbo5.png) * SSH設定 * remote host=門市rpi ip ![](https://i.imgur.com/25voYNh.png) * 輸入帳號、密碼 ### 印表機 ```bash #查詢印表機連接 systemctl list-unit-files pos-print.service #查詢印表機狀態 systemctl status pos-print #印表機服務重啟 sudo systemctl restart pos-print #遠端測試列印(不是每台都有放test_print_receipt.sh) /opt/tk3c/bin/test_print_receipt.sh ``` ### API ```bash # 狀態查詢 sudo systemctl status tomcat # 重啟Tomee sudo systemctl restart tomcat ``` ### MQTT ```bash # 重啟 sudo systemctl restart mosquitto ```

    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