# 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)