Keisuke-Takagi
    • 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
    • Make a copy
    • 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 Make a copy 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
    --- tags: エネワールド, robots: noindex, nofollow lang: ja-jp dir: ltr breaks: false --- # AWS/Laravel 開発環境構築マニュアル(Amazon Linux版) --- ## 本マニュアルで設定する内容 * インスタンスは、Amazon Lunux 2 t2.micro * Laravel/PHP, Mysqlで環境構築する * バージョンについては、Homesteadのv11.2.2と統一すること * Web サーバー Apache * Github からソースコードのCodeDeploy自動デプロイができる * 自動デプロイの設定内容はロードバランサー非対応 * ~~S3による画像アップロード~~ ## 開発環境や使用モジュールについて | OS | AmazonLinux | | -------------- | ----------- | | パッケージマネージャー |yum, Composer(Laravel)| | データベース| MySql | | フレームワーク |Laravel| | 言語 |PHP | | 自動デプロイ |AWSCodeDeploy| [Laravel7系 サーバ要件について](https://readouble.com/laravel/7.x/ja/installation.html) ## 主要なファイルの編集コマンド #### Apache ディレクトリ構造 * Apacheエラーログ /var/log/httpd * Laravel アプリケーションパス(今回の実装ではこの下に配置) * `$ cd /var/www/html` htmlの下の箇所にgithubと同じコードを CodeDeploy経由でデプロイするよう作成 * php エラーログ編集コマンド * `$ sudo vim /var/log/php_errors.log` * Apache 設定ファイル * `$ sudo vim /etc/httpd/conf/httpd.conf` ## EC2 環境開発マニュアル > [color=black] ### 1. Laravel アプリケーション作成 * Gitに ファイルをアップロード 仮想環境上に**Homesteadのv11.2.2** で環境構築した アプリケーションをpushしておく --- <br/> #### ==全てのEC2工程はリージョンをアジアパシフィック(東京)で行うことに気をつける== <br/> --- ### 2. EC2インスタンス作成 → EIP を使ったssh 接続 #### I. EC2インスタンス作成 ##### 参考サイト 「AWSで自動デプロイ」を基本参考にEC2インスタンスを作成する。 [AWSで自動デプロイ](https://qiita.com/nasuB7373/items/081f5974e31419a1a844#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E7%92%B0%E5%A2%83%E3%81%A8github%E4%B8%8A%E3%81%A7%E3%81%AE%E8%A8%AD%E5%AE%9A) **Ec2作成手順** 1. AMI を選択 2. 仮想サーバーの選択(無料枠は t2.microのみ) →選んだら「確認と作成」を押す 3. 確認画面がでるのでそのまま「起動」 4. キーペアの作成からキーペアを作る (既にある場合は不要) 5. 作成したキーペアをダウンロード(既にある場合は不要) [重要] DLしたキーペアファイルは保管する     (~/.sshにまとめる) #### II. EIPの関連付け EC2インスタンスにEIPを関連づける ElasticIPをコンソールから選択 ![](https://i.imgur.com/Rn7Zalj.png) 関連付け設定項目 ![](https://i.imgur.com/BDJniob.png) #### III. EC2にSSH接続 1. キーの配置 キーペア(〇〇.pem ファイル)を ~/.ssh ディレクトリに配置する。 又必要であれば、キーの権限を付与もする。 2. カレントディレクトリでEC2接続コマンドを入力 $ ssh -i .ssh/設定したキーペア名.pem ec2-user@「パブリックDNS」 3. 接続するかの確認にyes Are you sure you want to continue connecting (yes/no)? yes #### IV. 接続後の確認 ##### Amazon Linux2 のインスタンスに接続できるか確認 ![](https://i.imgur.com/1zZaTVs.png) ##### CodeDeployAgentが正常にインストールできているか確認 ![](https://i.imgur.com/KiUDzhH.png) --- ### 3. Apacheのインストール # パッケージインストーラーのアップデート $ sudo yum update # Webサーバー(apache)のインストール $ sudo yum install httpd # apache起動 $ sudo systemctl start httpd # apacheの確認 $ sudo systemctl status httpd → Active: active (running) か確認 ここまでうまくできていれば、 「パブリック IPv4 DNS」で画像のページが表示されるか確認 ![](https://i.imgur.com/mZH7dsX.png) --- ### 4. Linuxの設定とPHPインストール * [参考URL](https://qiita.com/nagahama/items/2fdc820791bee5d564ca) * Linux OS 初期設定 日付をJSTに設定する $ date →UTCになっていることを確認 $ sudo cp /etc/localtime /etc/localtime.default $ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime $ sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.default $ sudo vim /etc/sysconfig/clock [vim内] ZONE="Asia/Tokyo" UTC=false --- $ date →JSTになっているか確認 $ sudo vim /etc/sysconfig/i18n [vim内編集] LANG="ja_JP.UTF-8" $ sudo reboot # Amazon LinuxにデフォルトインストールされているRemi リポジトリを有効化 $ sudo yum-config-manager --enable epel $ sudo amazon-linux-extras install epel $ sudo yum install epel-release $ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm # PHP のインストール $ sudo yum install --enablerepo=remi,remi-php74 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt $ sudo amazon-linux-extras install php7.4 # そのほかに必要なパッケージをインストール $ sudo yum install --enablerepo=remi,amzn2extra-php7.4 php-xml php-mbstring # シンボリックリンクの作成(remi パッケージの場合は php -v でバージョン確認できるため、不要) $ sudo ln -s /usr/bin/php74 /usr/bin/php $php -v →PHP 7.4.9 になるか確認 $ sudo cp /etc/opt/remi/php74/php.ini /etc/opt/remi/php74/php.ini.default # phpの設定ファイルの編集 $ sudo vim /etc/opt/remi/php74/php.ini [vim内] # HTTPヘッダにPHPのバージョンを記載しない(一応セキュリティ的にOffにしておいたほうが良い) # expose_php = On expose_php = Off # メモリ上限を引き上げる(結構デフォルトのメモリは少なめなので増やしておくことが多い) # memory_limit = 128M memory_limit = 256M # POST送信の許容サイズを引き上げる # post_max_size = 8M post_max_size = 16M # アップロードファイルの許容サイズを引き上げる(スマホの写真のサイズが大きくなっているので、2Mだとほぼ画像投稿できないので増やす) # upload_max_filesize = 2M upload_max_filesize = 16M # timezoneの設定 # date.timezone = date.timezone = Asia/Tokyo --- # php-fpmを再起動し、更新 $ sudo systemctl restart php74-php-fpm # 更新内容等でエラーがないか起動確認 $ sudo systemctl status php74-php-fpm →runningか確認 --- ### 5. ComposerとLaravel の導入 1. composerインストール [Composerインストール参考サイト](https://qiita.com/miriwo/items/b25f9d4d74b7103f6ff6) compsoer の公式ページDownload Composerの項目のコマンドを順に打ち込む [Composer 公式](https://getcomposer.org/download/) その後は、下のコマンドを順に実行する # composer 実行ファイルの移動 $ sudo mv composer.phar /usr/local/bin/composer # composer の実行 $ php /usr/local/bin/composer →composer と表示されるか確認 # 環境変数の設定 $echo "export PATH=/home/ユーザ名/.config/composer/vendor/bin:$PATH" >> ~/.bash_profile # 環境変数の更新 $ source ~/.bash_profile # 確認 $ composer #### 4. git のインストール $ sudo yum install git →Is this ok [y/d/N]: y ##### 5. CodeDeployでの自動デプロイ設定 #### 参考サイト [AWSで自動デプロイ](https://qiita.com/nasuB7373/items/081f5974e31419a1a844#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E7%92%B0%E5%A2%83%E3%81%A8github%E4%B8%8A%E3%81%A7%E3%81%AE%E8%A8%AD%E5%AE%9A) * セキュリティグループ の確認(設定されていなければしておく) ![](https://i.imgur.com/FfkjdOI.png) ##### ローカルソースコードにCodeDeployの設定ファイルの追加 [Gitubリンク](https://github.com/aws-samples/aws-codedeploy-samples/tree/master/applications/SampleApp_Linux) Githubのリンクから「scripts」フォルダと 「asspec.yml」をDLし、追加 ==両方ともソース元のルートディレクトリに配置すること== また、「asspec.yml」の内容も修正し、プッシュする ``` version: 0.0 os: linux files: - source: / ←ココのみ修正 destination: /var/www/html/ hooks: BeforeInstall: - location: scripts/install_dependencies timeout: 300 runas: root - location: scripts/start_server timeout: 300 runas: root ApplicationStop: - location: scripts/stop_server timeout: 300 runas: root ``` scripts/start_serverを下の内容に編集 ``` #!/bin/bash cd /var/www/html mkdir -p /var/www/html/vendor mkdir -p /var/www/html/storage mkdir -p /var/www/html/bootstrap/cache sudo chmod -R 777 /var/www/html/vendor sudo chmod -R 777 /var/www/html/storage sudo chmod -R 777 /var/www/html/bootstrap/cache sudo chmod 777 /var/www/html/composer.lock composer install php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear php artisan config:cache php artisan migrate service httpd start ``` ##### CodeDeployの設定 * デプロイグループ作成時、AWS Systems Managerのインストールはデフォルトのまま。(使用すると料金請求がくる可能性がある) * デプロイ作成時、追加のデプロイ動作設定の項目 * このインスタンス上のライフサイクルイベントの障害で、デプロイを失敗させないのチェックを外す * コンテンツオプション - オプショナル → deployの失敗にチェック * 自動デプロイ時のデプロイエラー対処法 * The deployment failed because a specified file already existsが発生 $ cd /var/www/html # 隠しファイファイル等も含むファイル確認 $ ls -la # html直下の全ファイルの削除 $ sudo rm -R -f ファイル名or フォルダ名 # public がない場合はApache起動しないため空ディレクトリ作成 $ mkdir public 以上の作業が終わったら一度EC2コンソールへログインし、 コミットをpushされたときに、作成したCodePipelineで、 成功がでるか確認する。 [html 直下のファイルを全て削除しやり直すという内容の記事](https://lms.sejuku.net/question/detail/2229) [documnet](https://docs.aws.amazon.com/codedeploy/latest/userguide/troubleshooting-deployments.html) * その他は記事の内容で設定する。 ##### CodePipelineの作成 https://qiita.com/nasuB7373/items/081f5974e31419a1a844#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E7%92%B0%E5%A2%83%E3%81%A8github%E4%B8%8A%E3%81%A7%E3%81%AE%E8%A8%AD%E5%AE%9A 記事の内容で設定し、 何かしらのコミットをリモートリポジトリにプッシュ後、 自動でデプロイが成功するか確認 ##### デプロイ成功時のログ(上二つがgitコミットデプロイ成功例) ![](https://i.imgur.com/mkAHu62.png) ##### 自動デプロイ成功時 ![](https://i.imgur.com/03FnTQG.png) 選択した、ブランチの Git Push時にコミットが変更されていれば成功 ##### エラーがあった時 AWS web console-> CodePipeline->デプロイ履歴等から、 デプロイのエラー文を確認 ##### 画面の確認 * ブラウザでIPアドレスを入力し、変更内容が実際に変更されているか確認 #### デプロイ時、画面にデザイン等が反映されていない時 * Laravel のキャッシュが原因の場合があるので以下サイトを参考にキャッシュを削除すること [キャッシュクリア系コマンド](https://qiita.com/Ping/items/10ada8d069e13d729701) --- ### 6. Laravelアプリケーションのファイル設定 [参考サイト](https://qiita.com/masataka715/items/6e46f1f5e53bdff6cd3d) * キャッシュ自動デプロイが成功したのに変更が反映されない時 [composer iunstall後のキャッシュについて](https://qiita.com/qiita-kurara/items/d37dbc5b67e6b6dfbe1d) # composer キャッシュクリア $ php artisan cache:clear $ php artisan config:clear $ php artisan route:clear $ php artisan view:clear # キャッシュの作成 $ php artisan config:cache $ cd /var/www/html * .env の設定 # .envの設定 .env.exampleがある場合 $ cp .env.example .env .env.exampleがない場合 $ sudo touch .envを実行 githubにあるenv.exampleの内容をEC2 の.envに全コピーし、次へ $ sudo vim .env [env内] 該当箇所のみ変更する他はそのまま APP_NAME=Laravel APP_ENV=production APP_KEY= APP_DEBUG=false APP_URL=http://[パブリックIP] # key generete $ sudo php artisan key:generate $ sudo cat .env APP_KEYの内容に自動割り振りされているか確認 --- ### 7. Apacheの設定 [参考サイト](https://qiita.com/masataka715/items/6e46f1f5e53bdff6cd3d) #バックアップファイルの作成 $ sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.default # 設定ファイルを開く $ sudo vi /etc/httpd/conf/httpd.conf # 以下に変更 DocumentRoot "/var/www/html/public" 最終行に以下を追記 # .htaccess 有効化 <Directory /var/www/html/public> AllowOverride All </Directory> # apache 再起動 $ sudo service httpd restart (Apache設定変更時は「sudo service httpd restart」で再起動し、変更を反映) $ sudo service httpd status →running になるか確認 [エラーが出たときの参考サイト](https://qiita.com/ponsuke0531/items/cc07807d92ecad60a82f) --- ### 8. EC2 インスタンスの設定 * php.iniの設定 sudo vim /etc/opt/remi/php74/php.ini [vim] ;extension=mysql ↓に変更 extension=curl * swapの設定(メモリ不足対策) * 注) メモリが不足している場合のみ行う [メモリ不足対策参考サイト](https://qiita.com/na0AaooQ/items/278a11ed905995bd16af) # 512MB のswapファイル作成 $ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512 $ sudo chmod 600 /swapfile1 $ mkswap /swapfile1 $ swapon /swapfile1 --- ### 9. mysql 設定 #### 1. mysql のインストール # 不要なmariadbの削除 $ sudo yum remove mariadb-libs # リポジトリインストール $ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm # mysql-community-server(パッケージ)インストール $ sudo yum install --enablerepo=mysql80-community mysql-community-server # mysqlのインストール $ sudo yum install --enablerepo=mysql80-community mysql-community-devel # mysql ログファイルの作成 $ sudo touch /var/log/mysqld.log # インストールされたmysql の確認 $ yum list installed | grep mysql # 起動と確認 $ sudo service mysqld start $ systemctl status mysqld.service # インスタンスの起動と同時にmysqlも起動するよう設定 $ sudo chkconfig mysqld on #### 2. mysql初期設定 1. mysql パスワード確認 $ sudo cat /var/log/mysqld.log | grep password ↓mysqlの初期パスワードを確認しコピーをする ![](https://i.imgur.com/fJ7h7dY.png) 2. mysql パスワード設定 以下の設定を行う * rootユーザーのパスワード設定 * ログイン等で使用するユーザーの作成 * Laravelアプリの.envで環境変数を設定 # 初期設定 $ mysql -u root -p →1.で確認したパスワードでログイン # Mysql DB 制約の確認 $ SHOW VARIABLES LIKE 'validate_password%'; mysql> set password for 'root'@'localhost' = '任意のパスワード' ※デフォルだと制約が厳しいので、パスワードジェネレータを使用するとよい //普段ログインで使用するアカウントの作成 # (以下2行は必要に応じて入力) # 制約を緩める mysql> set global validate_password.policy=LOW; # パスワードの文字数制約を変更 mysql> set global validate_password.length=8; # ユーザー作成処理(この場合はユーザー名: u_netex, パスワード: password で設定される) mysql> CREATE USER u_netex@'localhost' IDENTIFIED BY 'password'; # (以下2行は制約を緩めた場合に入力) mysql> set global validate_password.policy=MEDIUM; mysql> set global validate_password.length=12; ユーザーをDBへ紐づけ mysql> GRANT ALL PRIVILEGES ON netex.* TO u_netex@'localhost'; mysql > exit $ mysql -u u_netex -p →新規作成したユーザーでログインできるか確認 # .envの設定 $ cd /var/www/html $ sudo vim .env [vim内] DB_USERNAME=設定したユーザー名 DB_PASSWORD=設定したパスワード #Laravel キャッシュ削除 php artisan cache:clear php artisan config:clear php artisan config:cache # 以下のコマンド等を打って envが反映されたか確認する $ cd /var/www/html $ php artisan db:seed →正常に動作すれば設定完了 --- ### メモリ不足の時 * スワップファイルを作成し、メモリを増やして対応 [スワップファイルの作成](https://qiita.com/na0AaooQ/items/278a11ed905995bd16af) * Composer 系のコマンドの場合は1カ月単位等でコミットを分けて composer install もしくは、開発中定期的に、composer installをしておくなどの対応が必要 --- ### .env の値が反映がされない時 Laravel の仕様で、config/の下のディレクトリ以外で env()を使い環境変数を確認しよとすると反映されない。 config/ではenv()を使ったままでいい。 [対策] config配下ファイルに一度設定し、呼び出し元でconfig()で呼び出す。 ✖「本番環境で値が反映されない書き方」 $env = env('APP_ENV', 'production'); 〇「本番環境での動作も考えた書き方」 # 1. config配下のディレクトリでenv()で値を参照する [config/app.php] 'env' => env('APP_ENV', 'local'),  # 2. 使用したい箇所でconfig()を使ってキーを指定し値を参照 $env = config('app.env'); --- ## AWS 費用詳細 * S3 #### 無料利用枠について(2020/09/24 公式ページ引用) AWS 無料利用枠の一環として、Amazon S3 を無料で開始できます。 AWS の新規のお客様は、サインアップしていただくと、S3 標準ストレージクラスで 5 GB の Amazon S3 ストレージ、20,000 GET リクエスト、2,000 PUT、COPY、POST、 あるいは LIST リクエスト、データ送信 15 GB を毎月、1 年間ご利用いただけます。 [S3 費用詳細](https://aws.amazon.com/jp/s3/pricing/) * EC2 #### 無料利用枠について(2020/09/24 公式ページ引用) 無料利用枠内に抑えるには、EC2 マイクロインスタンスのみを使用してください。 [EC2費用詳細](https://aws.amazon.com/jp/ec2/pricing/) * Elastic IP #### 無料利用枠について(2020/09/24 公式ページ引用) 次の条件がすべて満たされている限り、Elastic IP アドレスに料金は発生しません。 * インスタンスのElastic IP アドレスが EC2 インスタンスに関連付けられている。 * インスタンスのElastic IP アドレスに関連付けられているインスタンスが実行中である。 * インスタンスのElastic IP アドレスしか添付されていない。 [Elastic IP 料金システム説明](https://cloud5.jp/ec2-eip/) [Elastic IP 料金(Amazon公式)](https://aws.amazon.com/jp/ec2/pricing/) * Codepipeline(自動デプロイ等に使用) 1 か月あたり 1 つ無料 その他、毎月アクティブなパイプライン*1つにつき1.00USD が課金される ## AWS 用語まとめ * キーペア * インスタンスへの接続時に身分証明に使用するセキュリティ認証情報のセットであり、プライベートキーとパブリックキーで構成 * Elastic IP * Elastic IPアドレス(EIP)とは A. 固定化されたIPアドレス * メリット * IPアドレスが固定化される * デメリット * お金がかかる可能性があり * なぜ必要か? パブリックアドレスはEC2インスタンスに固定化されず 変化することがあるため 実際最初にインスタンス停止、 再起動すると変化した * セキュリティグループ AWSでホワイトリスト方式で外部からの通信を許可する設定 セキュリティグループを設定しないと外部との通信は全て遮断される [参考サイト1](https://recipe.kc-cloud.jp/archives/22) [参考サイト2](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/security-group-rules-reference.html#sg-rules-web-server) * AWS Systems Manager (SSM) 主な機能 ・リソース状況の可視化 ・定型作業の実施 ・インタラクティブな操作 ・アプリケーションの設定管理 [参考サイト](https://blog.serverworks.co.jp/tech/2020/04/16/systems_manager_yattemiyou/) * remiリポジトリ [参考サイト](https://akamist.com/blog/archives/648) * 自動デプロイ設定時に編集するappspec.ymlについて * files: * デプロイ先とデプロイ元のディレクトリを指定 source: github上のディレクトリを指定 files: Ec2上のディレクトリを指定 * hooks: * Deploy時のイベントフックを指定 [appspec.yml のhooksについて](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html) デプロイ時のイベントをフックできる ⇩AWSが用意しているイベントフックの種類 ![](https://i.imgur.com/h5qVep0.png)

    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