# 3/22 社課 ## 黑客社 ###### tags: `黑客社` `黑客社社課` --- 前兩次上課沒來的舉手 ---- 前兩次的簡報 [第一次](https://goo.gl/GRgVWn) [第二次](https://hackmd.io/p/SJF4UMzUM) --- 好大家來記得 我們在用伺服器架自己網頁吧 --- 黑客社伺服器 登入方式 ``` $ ssh hackersir@140.134.208.99 -p 你分配到的port ex . ssh hackersir@140.134.208.99 -p 20050 ``` 忘記密碼/連不上的舉手 --- ![](https://i.imgur.com/vpIvu0Y.png) --- ![](https://i.imgur.com/tqBjm9g.png) --- 前次提要 --- **Apache Http Server** - 最有名的網站伺服器 - 不需收費的軟體 - 可以在windows平台與Linux平台上執行 - 模組化的功能調整,支援動態載入模組 - 安裝容易,可用命令列與圖形介面安裝 --- apache2設定檔 --- 主要設定檔: ``` /etc/apache2/apache2.conf ``` 定義Apache伺服器的主要行為與環境變數 --- apache2.conf中可以引入(include)的其他設定檔 |位子|說明| | -------- | -------- | |/etc/apache2/envvars|Apache環境變數| /etc/apache2/httpd.conf|伺服器的變數設定:逾時值、最大連線數等… /etc/apache2/ports.conf|Apache監聽的IP位址與通訊埠(port) /etc/apache2/conf.d|使用者自訂的的設定檔 --- apache2.conf中可以引入(include)的其他設定檔 |位子|說明| | -------- | -------- | /etc/apache2/sites-available/|可用虛擬主機的設定檔目錄 /etc/apache2/sites-enabled/|已啟用的虛擬主機的設定檔目錄 /etc/apache2/mods-available/|可用模組(module)的目錄 /etc/apache2/mods-enabled/|已啟用模組的目錄 --- 我們先來開啟模組 --- 我們先下ls 看看內建了哪些模組 ``` $ ls /etc/apache2/mods-available/ ``` ![](https://i.imgur.com/sCQIzdG.png) --- 然後再用ls看看開啟了哪些模組 ``` $ ls -l /etc/apache2/mods-enabled/ 其中他是用指標把這資料夾檔案和available檔案連在一起 所以是同一個檔案 但是只有在enabled這資料夾出現的有使用到 沒有做連結的就沒使用 ``` ![](https://i.imgur.com/Mpknd5X.png) --- 那要如何開啟模組呢 假如我要打開 proxy這模組就下 ``` $ sudo a2enmod proxy ``` 然後再把 apache2重開才會啟用 ``` $ sudo service apache2 restart ``` 關閉則是 ``` $ sudo a2dismod proxy ``` --- 接下來講虛擬主機 --- 虛擬主機(Virtual Host) 的定義: 一台 Apache 伺服器 可以處理超過一個 domain(網域) 例如有兩個網址都同時對應到該主機 IP,而主機能依照網址不同給與不同的網頁。 ex. http://123ojpp.me/ http://test.123ojpp.me --- 那麼我們先寫第二個網頁 先建立 一個資料夾 當第二個網頁的目錄 ``` $ sudo mkdir /var/www/html2 ``` 然後建立首頁 ``` $ sudo vim /var/www/html2/index.html ``` 然後塞一些文字存檔案 ![](https://i.imgur.com/LUOmSor.png) --- 那是如何設定呢 修改/新增 sites-available 的檔案 --- 我們來看看虛擬主機預設設定檔 ``` sudo vim /etc/apache2/sites-available/000-default.conf ``` ![](https://i.imgur.com/UON1tdn.png) --- 我們可以看到 設定檔是被 ```clike= <VirtualHost *:80> </VirtualHost> ``` 包起來 而80則是剛剛說的 在80port listen 而可以連續使用好幾個這個標籤來表示不同設定 --- 我建立一個最基本的來解釋 ```clike= <VirtualHost *:80> ServerName www.example.com #哪個網域使用這個設定檔 DocumentRoot /var/www/html2 #網址導向哪個目錄 ErrorLog ${APACHE_LOG_DIR}/error.log #錯誤訊息存哪 CustomLog ${APACHE_LOG_DIR}/access.log combined # 記錄檔存哪 </VirtualHost> ``` --- 然後在/etc/apache2/sites-available/ 建立新的設定檔 ``` #ex. 乖小孩不要命這種名稱 $ sudo vim /etc/apache2/sites-available/test.conf ``` ![](https://i.imgur.com/B5sVCXB.png) --- 所以我們把這些設定丟到新的設定檔裡 ``` $ sudo vim /etc/apache2/sites-available/test.conf ``` (域名 記得改成自己 ) ```clike= <VirtualHost *:80> ServerName test.123ojpp.me #👈這個記得改成自己的 DocumentRoot /var/www/html2 ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> ``` --- 然後存檔(:wq) 使用a2ensite指令啟用剛剛的設定檔 ``` $ sudo a2ensite test ↑你設定檔的名稱 ``` 相同的如果要取消設定用 ``` $sudo a2dissite test ``` --- 然後讓apache2重新讀取設定黨 ``` $ sudo service apache2 reload ``` --- 打開網頁看看 ![](https://i.imgur.com/bov1nR1.png) --- 會動的後端 --- 我們先教 # flask 對之前學python比較直觀 --- 我們一開始先不用伺服器 先在自己電腦上架 --- 那麼我們和上學期一樣 先到pip 安裝flask (記得用工作管理員開cmd) ``` pip install flask ``` --- flask 這個python套件 可以讓你用python指令建立網頁伺服器 首先我們先打開一個建立一個python檔(.py) 然後 用你喜歡的編譯器 (ex. notepad++) --- 然後 導入 flask ```python= from flask import Flask ``` 然後定義一個flask的 app變數 ```python=+ app = Flask(__name__) ``` --- 再來 我們定義 根目錄(首頁) 就是網頁http://some.thing/ 的 ”/“ ```python=+ @app.route("/") def hello(): return "Hello World!" ``` 如果我們要http://some.thing/123ojp 就是 ```python=+ @app.route("/123ojp") def 123ojp(): return "Hello World!" ``` 而return 就是要傳什麼東西給瀏覽器 --- 最後我們給他 run的指令 ```python=+ app.run() ``` --- ```python= from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" app.run() ``` ![](https://i.imgur.com/KnuwIsz.png) --- 然後用cmd 執行它 ```cmd= C:\> python main.py ``` ![](https://i.imgur.com/ZK8fBin.png) --- 打開 http://127.0.0.1:5000/ 看看 ![](https://i.imgur.com/1WUYF9D.png) --- 那麼我們可以return 看看其他東西 試試看 ```python= return str(1+1) ``` flask只接受str 字串形式 ![](https://i.imgur.com/01NmsnE.png) --- 打開後我們得到 2 ![](https://i.imgur.com/1bJ32YP.png) --- 那麼這有什麼屁用呢 這代表我們可以 輸入一串python程式碼叫他做 然後再網頁吐出來結果 我們可以試試看叫他吐時間 ```python= from flask import Flask import time app = Flask(__name__) @app.route("/") def index(): return str(time.strftime("%H:%M:%S")) app.run() ``` --- 我們可以看到 重新整理 他就會換時間 ![](https://i.imgur.com/j3tL55v.png) ![](https://i.imgur.com/ucMGemY.png) --- 所以這到底能幹嘛呢 假如 我們把程式碼 塞在 def 和 return 中間 他就會一行一行執行 在return你要顯示的東西 所以 可以用我們上學期爬蟲 讓他吐在你網頁上 --- 接下來教flask怎麼讀USER傳送的資料 --- 上學期有講過 http 方法 有 POST 和 GET 平常瀏覽網站 就用GET 跟伺服器拿網頁 而POST 是拿來丟東西給伺服器 --- 通常在html會用下列code 做post ```htmlmixed= <form action="" method="post"> <input type="text" name="text"> <button type="submit">送出</button> </form> ``` ![](https://i.imgur.com/n6ZUL7n.png) --- 而後端要怎麼處理拿到的資料呢? 首先先引入request ```python= from flask import Flask,request ``` 我們在@app.route 後面要先定義我們要使用POST ```python=+ @app.route('/', methods=['GET', 'POST']) ``` --- 如果是 post 把拿到的內容存到aaa 並丟還給使用者 不是則回覆表單 ```python=+ def index(): if request.method == 'POST': aaa = str(request.form['word']) return aaa else: return'''<form action="" method="post"> <input type="text" name="word"> <button type="submit">submit</button> </form> ''' ``` --- 完整code ```python= from flask import Flask,request app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': aaa = str(request.form['word']) return aaa else: return'''<form action="" method="post"> <input type="text" name="word"> <button type="submit">submit</button> </form> ''' app.run() ``` --- 接下來來教render_template這個function 他可以讓你把「變數」 放進 「網頁」裡 然後 吐出一個美美的網頁 ![](https://i.imgur.com/BK1k6fm.png) --- 首先要引入render_template ```python= from flask import render_template ``` --- 接下來我們要一個網頁 和 一個變數給flask改成文字 我們命名一個叫做time的變數 並把他用 {{}} 刮起來 這樣 flask會收到並改他 ![](https://i.imgur.com/6ofzuBi.png) --- 然後在程式碼資料夾建一個叫做"templates"的資料夾 並把網頁放在裡面 ![](https://i.imgur.com/MtmFtdI.png) --- 而程式碼方面則用 ```python= return render_template("檔案名稱",網頁裡的變數=程式碼的變數) ``` 例如: ```python= @app.route("/") def index(): nowtime = str(time.strftime("%H:%M:%S")) return render_template("index.html",time=nowtime) ``` --- 例子: ```python= from flask import render_template,Flask import time app = Flask(__name__) @app.route("/") def index(): nowtime = str(time.strftime("%H:%M:%S")) return render_template("index.html",time=nowtime) app.run() ``` --- 可以看到 原始碼被替換成我們傳入的變數 ![](https://i.imgur.com/Iql1ys5.png) --- 接下來教flask怎麼傳檔案 --- 使用send_file這功能 先引入 ```python= from flask import send_file ``` --- 使用方法 ```python= return send_file("檔案位子 (相對位子為終端機開始計算)") ``` ex . ```python= @app.route("/") def index(): return send_file("123.jpg") ``` --- 這樣我們打開就會得到美美的圖片 ![](https://i.imgur.com/oDKVHvr.jpg) --- 接下來教 如何像apache 一樣 資料夾裡有什麼就吐出什麼 我們先def 一個新的路徑 後面加入\<path\> 告數flask他是變數 ```python= @app.route('/file/<path>') ``` 然後()內填入path跟這程式講會有一個path直進來 ```python=+ def send__file(path): ``` 最後用 send_file 把值吐出去 ```python= return send_file(path) ``` --- ```python= @app.route('/file/<path>') def send__file(path): return send_file(path) ``` 我們試試看拿拿看http://127.0.0.1:5000/file/main.py ![](https://i.imgur.com/PyCBoIz.png) --- 所以我們可以把css js 等文件用這方式吐出來 ex. ```python= @app.route('/js/<path>') def send_assets_js(path): return send_file('js/'+path) @app.route('/css/<path>') def send_assets_css(path): return send_file('css/'+path) @app.route('/img/<path>') def send_assets_img(path): return send_file('img/'+path) ``` --- 最後大家選一個美麗的模板 然後 讓網頁顯示現在時間 ![](https://i.imgur.com/BK1k6fm.png) --- 不知道大家在開網頁時有沒有注意到 終端機上面寫:http://127.0.0.1:5000/ 那麼要如何 修改讓他開在不同port和ip呢? ![](https://i.imgur.com/vjw46YP.png) --- 我們只要在run後面加上參數就可以了 ```python= #app.run(host='{{ ip }}',port={{ port }}) #ex. app.run(host='0.0.0.0',port=1233) ``` 開在0.0.0.0代表開在所有網卡 大家可以在網址列輸入別人的ip和port 應該就可以看到別人開的網頁 --- 那麼我們要怎麼把他放到伺服器上呢 我們可以直接讓他開在80 port上 然後執行 ```python= app.run(host='0.0.0.0',port=80) ``` 因為網頁就是開在80port上 註:記得要把apache2 關掉 因為apache2已經佔用 80port了 ``` sudo service apache2 stop ``` --- 那麼你們會想說 如果我想要用 apache的「虛擬主機」 又想用 flask 怎麼辦 --- 這時候就要用到apache一個叫proxy的模組 他可以幫你把在別的「port」的網頁 投射到不同的 「網域」 --- 首先 我們先把flask 修改成開在本地 ```python= app.run(host='127.0.0.1',port=20000) ``` ![](https://i.imgur.com/O31WVUg.png) --- 我們把flask 傳到server上 ![](https://i.imgur.com/1U4nbg4.png) --- 先更新apt-get 清單 ``` $sudo apt-get update ``` 然後在server上安裝python ``` $ sudo apt-get install python2.7 ``` 再安裝flask ``` $sudo apt-get install python-flask ``` 啊要不要裝 pip 看個人 ``` $ sudo apt-get install python-pip ``` --- 再來 我們先把apache2的 proxy模組開啟 ``` $ sudo a2enmod proxy proxy_balancer proxy_http ``` --- 然後建立一個新的 虛擬主機 設定檔 ``` $ sudo vim /etc/apache2/sites-available/flask_proxy.conf ``` 裡面塞入 ```htmlmixed= <VirtualHost *:80> #虛擬主機要設定的域名 ServerName flask.123ojpp.me #⬆️改成自己網域 #開啟反向代理 ProxyRequests Off ProxyPreserveHost On #表示要將哪個網址轉到導虛擬主機 剛剛我們設定再http://127.0.0.1:20000/ ProxyPass / http://127.0.0.1:20000/ ProxyPassReverse / http://127.0.0.1:20000/ #一些proxy設定 <Proxy *> Order Deny,Allow Allow from all </Proxy> </VirtualHost> ``` --- 啟用設定檔 並重新開啟apache2 ``` $ sudo a2ensite flask_proxy ``` ``` $sudo service apache2 restart ``` --- 最後 執行python ``` $ python2.7 flask1.py ``` ![](https://i.imgur.com/D5moanu.png) ![](https://i.imgur.com/08MOL7Y.png) --- 這時候又會發生一件事 如果你把ssh 關掉了 python 就不會繼續執行 網頁就掛了 ![](https://i.imgur.com/eIXGdhn.png) --- 這時候要用tmux 先安裝 ``` sudo apt-get install tmux ``` ![](https://i.imgur.com/IaYxtaC.png) --- 然後我們下 ``` $ tmux ``` 就會看到一個乾淨的頁面 你們可以把它想成一個新的「視窗」 ![](https://i.imgur.com/VxMKT5R.png) --- 然後我們把python flask開啟 ``` $ python2.7 flask1.py ``` ![](https://i.imgur.com/NFoGbw6.png) --- 先按住ctrl 然後 b 放開後按 d (ctrl+b) (d) 我們就會退出到剛剛進tmux的頁面 ![](https://i.imgur.com/OVUNyCx.png) --- 我們把ssh關閉再重新整理會發現網頁還活著 因為他在背景執行了 如果要重新回到剛剛那個tmux視窗 下 ``` $ tmux attach ``` --- 如果想多開幾個「視窗」 在下一次tmux就可以了 然後 要切換視窗是 先按住ctrl 然後 b 再來案 s (ctrl+b) (s) 就可以上下左右切換了 ![](https://i.imgur.com/Zh1Gq6U.png) --- 延伸閱讀: [apache設定檔](https://lms.ctl.cyut.edu.tw/sysdata/53/20253/doc/bde3934073d34191/attach/1094276.htm) [tmux指令全集](https://gist.github.com/ryerh/14b7c24dfd623ef8edc7)