cjtsai
失蹤的c++殭屍
Disclaimer:
如果你覺得簡報很醜去找吳雅倫
我fork他的
由大公司在全世界各地建設伺服器機房,並將其出租,供使用者租賃伺服器資源,包括但不限於算力、DNS服務、防火牆及很多很多
一般來說,自行架設以上所有資源並非不可行,然而其代價過大,若無大量需求,向供應商租借更為方便
不同於家用電腦,伺服器大多使用Linux作業系統,並需要24hr開啟,這會對平常使用的電腦造成負擔,所以大多數人會選擇多放置一台微型電腦或向雲端服務供應商租借伺服器
GCP (Google)
Azure (Microsoft)
AWS (Amazon)
Digital Ocean
linode, oracle, bluehost ...
台灣的(通常很貴): 中華電信、國雲網路
其實用最大的就好了
像是AWS最近也才開了台北區
為了架我的網站 我用過挺多的
AWS: 很喜歡偷收莫名其妙的小錢 買之前看清楚
GCP: 唯一不用綁信用卡就可以試用的 收費很玄
Digital Ocean: 收費比較透明 但帳號管理很爛
Azure: 這個我沒用過
目前AWS(Lightsail)使用中
全名 virtual private server
是CSP提供的一種服務,在伺服器上分割一部分資源供我們使用,有完整的檔案系統,並可以指派防火牆與靜態IP,在不同的地方有不同名字
AWS: Lightsail(你要用的打包好), EC2(全手動)
GCP: Compute Engine
Digital Ocean: Droplet
眾所周知,GCP提供每個新用戶300鎂的試用額度
這代表你可以開小帳去蹭
但這300鎂只能用三個月
另外的選項是去申請 GitHub Student Pack(一次性)
他會給你 Digital Ocean 200鎂可以用一年
然後因為我們很窮,所以這次要用GCP
但我們已經開好了所需的伺服器,所以問題不大
等下會按照組別把伺服器IP及密碼發下
這次不會再有相同金鑰然後有人搞事有人爆氣有人搞消失的事情發生了 真的 詳情請洽 2024 建北電資聯合寒訓 - 你資道我喜歡你嗎
禮拜一講過了基本的
但還有一些沒講到而我們需要用的
取代舊的不安全連線,如 telnet 你們前幾天才用過
建構安全的通訊與資料傳輸
功能很多 最常用的是連線登入遠端伺服器
你們應該也用過了
ssh username@hostip
可以透過密碼登入 也可以透過預先產生的金鑰
也可以預先建立設定檔多層跳轉
ssh 的另外一種用法
建電的電腦目前正在使用他來跟外面的網路溝通
建中網管中心的巢狀網路系統使得該電腦只得連接於內網
ssh tunnel:
Client
Server
reverse ":
Client
Server
data
轉發
透過提前允許server之某一port存取本伺服器的某一port
使接下來能透過這個tunnel存遠端傳送資料或甚至建立ssh連線
ssh -R external_port:localhost:local_port external_server_ip
ssh -R 25565:localhost:25565 203.64.52.132
從遠端複製資料回來或丟東西上去
scp local_file external_user@external_server:external_file
scp external_user@external_server:external_file local_file
or
前者是丟上去 後者是抓下來 跟cp的邏輯一樣
例
scp cjtsai@ruby.cjtsai.com:~/file file
你們可能在網路上看過這張梗圖
很顯然別人連不到你的localhost
但如果你真的很想跟別人分享你寫的東西但懶得部署怎麼辦
後面會教你怎麼部署
他可以讓你把內網的port轉發出去
而且超快 一行 事前準備不算
ngrok http 8000
但你直接打的話會發現
他叫你去官網註冊token 跟著做就對了
弄好後再打一次 他會給你一個網址 此時你的8000口就被轉發出去了
當然你想要轉發其他口也可以
但注意他是暫時性的 ctrl+c之後即會停止 長期的好像要錢
在檔案間建立連結
通常拿來在一些系統設定檔或是執行檔之間的關聯
像是可能會把
/usr/bin/g++-14 ln 到 /usr/bin/g++
ln -s /usr/local/bin/g++-13 /usr/local/bin/g++
剛剛講過
為甚麼要防火牆
曾經有sb問過 為甚麼會有人想攻擊我們的服務/伺服器
請先相信 任何連接上網路的服務即是標靶
你從來不會知道哪天哪個吃飽太閒的學生會去攻擊建中的網頁
或是哪個俄羅斯人會把你的社網偷走
iptables: 傳統 偏底層
nftables: iptables pro
firewalld: RedHat/Fedora/CentOS 使用
ufw: ubuntu 使用的高階防火牆 底層使用iptables
顯然我們今天要用 ufw
先安裝
sudo apt install ufw
ufw allow http
ufw allow https
ufw allow ssh
先允許一些請求通過防火牆
啟動防火牆
ufw enable
查看狀態
ufw status
如果你使用的是 VPS
基本上只有使用 ssh 連線的方式
所以如果你用 ufw 把 ssh 擋掉
那就謝謝再聯絡了
所以每次 ufw enable 之前記得確認有 allow ssh
我之前架遊戲server的時候就幹過這種事
笑死
還有 GCP 有神奇的後台可以溜進去改設定
AWS好像就沒有
不知道為甚麼要講這個
可能是因為你們等下剛好會用到 但不是很重要
他可以在本地覆寫 DNS 讓連結特定網址的人去到特定的ip
他可以讓你測試時不用等待 DNS server 的長時間延遲
或是噁心人 把他電腦的校網改成怪怪的東西
在你輸入一個網址時,你的伺服器會先去 hosts 檔找有沒有對應的 ip 有的話就連上去 沒有的話就去找全球的 DNS server
Unix: /etc/hosts
Windows: C:\WINDOWS\system32\drivers\etc\hosts
挺簡單 對
像是你希望 aawsodian.ckefgisc.org 指到 203.64.52.132
server-ip domain-name
203.64.52.132 aawsodian.ckefgisc.org
接在最下面即可
注意因為他是系統檔案要用sudo開
windows的話建議複製好一份改完拖進去
Nginx & Apache
伺服器硬體
伺服器軟體
電腦設備
網路設備
機房
作業系統
各種應用程式:
負責讓伺服器發揮它的功能
web server 包含了一連串控制網路用戶如何訪問託管檔案 。HTTP 伺服器是其中一個部份,它理解 URLs 與 HTTP(瀏覽器用來觀察網頁的協議)。它能透過域名(domain name)訪問託管的網站,並將其內容遞送到終端用戶的設備上。
看不懂?
就是判斷使用者輸入的網址,
給出相應的網頁內容!
(或是丟出 404)
其他用途:反向代理、Http Cache、負載平衡器
1. Apache HTTP Server
由 Tim Berners Lee 開發並於 1995 年發布
由 Apache 基金會維護。
為全球約 46% 的網站提供支持
2. NGINX
發音為“Engine X”
由 Igor Sysoev 於 2004 年發布
3. Microsoft IIS
1. Apache HTTP Server
2. NGINX
3. Microsoft IIS
我們今天要交的是 Nginx
Why?
安裝 Nginx
sudo apt update
sudo apt install nginx
配置 Nginx
Nginx 的設定文件都位於 /etc/nginx
目錄下
主要設定檔:nginx.conf
其他設定檔:/conf.d/*.conf
例如:iscoj 的文件放在 /conf.d/iscoj.fg.tp.edu.tw.conf 裡
主要設定檔:nginx.conf
user www-data; ##設定 Nginx 使用 www-data 用戶執行。
worker_processes auto; ##自動調整工作進程的數量
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf; ##包含額外的模塊配置文件
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
預設文件:
次要設定檔:
virtual host: 一機多站
差在哪?
/conf.d/*.conf
/sites-
available/*
/sites-enabled/*
sites-available 存放所有 vhost config
link 要啟動的 config 到 sites-enable
Apache 的管理方式
vhost config 寫法
先來看看 default 檔案
架設靜態網站的寫法
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
監聽80口 ipv4 & ipv6
設定靜態網頁的根目錄
index的檔案名稱
如果你有網域並且已經指過去 就要打在這裡
沒東西就跳404
vhost config 寫法
解析一下他的常見基本架構 - reverse proxy
upstream api {
server localhost:5000;
}
server {
listen 80;
listen [::]:80;
server_name dian.cjtsai.com;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://api/;
}
}
定義了要將 request proxy 過去的應用
主區段
監聽 80 port (http)
路由設定(其實這裡跟第10行衝突)
非常重要,是反向代理的主要設定區
透過proxy_pass 可以使 / 連結至5000口
vhost config 寫法
解析一下他的常見基本架構 - reverse proxy 例子
server {
server_name iscoj.fg.tp.edu.tw iscoj.ckefgisc.org;
location /{
proxy_pass http://tioj/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $http_host;
proxy_redirect off;
# 舊網址 to 新網址格式 (with s)
rewrite "^/problem/(.*)$" /problems/$1 permanent;
}
#iscoj auto refresh and external judge server connection
location /cable {
proxy_pass http://localhost:4000/cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400; # 1 day
}
}
vhost config 寫法
更多 - https
我們通常使用一個叫 certbot 的東西自動生成憑證與金鑰
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# 憑證與金鑰的路徑
ssl_certificate /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/privkey.pem; # managed by Certbot
}
server {
if ($host = iscoj.fg.tp.edu.tw) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = fgiscoj.fg.tp.edu.tw) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name iscoj.fg.tp.edu.tw fgiscoj.fg.tp.edu.tw;
return 404; # managed by Certbot
}
這次要監聽 443 口
憑證金鑰路徑 由certbot自動生成
使用多個網域時
透過這個自動轉發
也是certbot生成的
不懂?來看看 iscoj 的反向代理設定
這是舊版
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
# passenger_enabled on;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream vscode{
server 0.0.0.0:8443;
keepalive 16;
}
upstream websocket{
server 0.0.0.0:3000;
keepalive 16;
}
upstream tioj {
server 0.0.0.0:4000;
keepalive 16;
}
upstream qduoj {
server 0.0.0.0:1443;
keepalive 16;
}
upstream cms {
server 0.0.0.0:8890;
keepalive 8;
}
upstream cms-admin {
server 0.0.0.0:8891;
keepalive 8;
}
upstream cms-rank {
server 0.0.0.0:8892;
keepalive 8;
}
# fgiscoj -> qduoj
server {
listen 443 ssl;
listen [::]:443 ssl;
# 憑證與金鑰的路徑
ssl_certificate /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/privkey.pem; # managed by Certbot
root /var/www/html;
server_name fgiscoj.fg.tp.edu.tw;
location /{
proxy_pass https://qduoj/;
# 把 IP、Protocol 等 header 都一起送給反向代理的 server
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
server {
# SSL configuration
#
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# 憑證與金鑰的路徑
ssl_certificate /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/iscoj.fg.tp.edu.tw/privkey.pem; # managed by Certbot
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
# index index.html index.htm index.nginx-debian.html;
server_name iscoj.fg.tp.edu.tw iscoj.ckefgisc.org;
location /{
proxy_pass http://tioj/;
# 把 IP、Protocol 等 header 都一起送給反向代理的 server
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $http_host;
proxy_redirect off;
# 舊網址 to 新網址格式 (with s)
rewrite "^/problem/(.*)$" /problems/$1 permanent;
}
#iscoj auto refresh and external judge server connection
location /cable {
proxy_pass http://localhost:4000/cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400; # 1 day
}
location = /problem {
return 302 /problem/;
}
location = /vscode {
return 302 /vscode/;
}
location /vscode/ {
proxy_pass http://127.0.0.1:8443/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
location = /cms {
return 302 /cms/;
}
location /cms/ {
proxy_pass http://cms/;
}
location = /cms/admin {
return 302 /cms/admin/;
}
location /cms/admin/ {
proxy_pass http://cms-admin/;
}
location = /cms/ranking {
return 302 /cms/ranking/;
}
location /cms/ranking/ {
proxy_pass http://cms-rank/;
proxy_buffering off;
}
location /cms/<ANS> {
return 302 https://hackmd.io/_uploads/rJMJQzcNn.png;
}
location /cms/96 {
return 302 https://hackmd.io/@QYi6gllvSum0RZrW3jaysg/Sy75nf9Vn;
}
location /cms/96/ {
return 302 https://hackmd.io/@QYi6gllvSum0RZrW3jaysg/Sy75nf9Vn;
}
location /cms/2000000080{
return 302 https://hackmd.io/@ckefgisc-izcc/BkZzbzPQ0;
}
location /cms/2000000080/{
return 302 https://hackmd.io/@ckefgisc-izcc/BkZzbzPQ0;
}
}
server {
if ($host = iscoj.fg.tp.edu.tw) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = fgiscoj.fg.tp.edu.tw) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = iscoj.ckefgisc.org) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name iscoj.fg.tp.edu.tw fgiscoj.fg.tp.edu.tw iscoj.ckefgisc.org;
return 404; # managed by Certbot
}
如何啟動 nginx ?
# 啟用
sudo systemctl enable nginx
# 啟動
sudo systemctl start nginx
# 重啟
sudo systemctl restart nginx
# 更新設定檔後 reload
sudo systemctl reload nginx
# 關閉
sudo systemctl stop nginx
# 查看狀態
sudo systemctl status nginx
##
# 無法啟動?
# 檢查誰占用了 80 port (通常是 apache2)
sudo lsof -i -P -n | grep LISTEN
# 把 apache 關掉
sudo systemctl stop apache2
nginx 更多指令
# 如果你沒有systemctl 可以使用nginx -s下達各種指令
nginx -s start/stop/reload
# 檢查conf檔案是否可用
nginx -t
# 自訂義conf檔案路徑
nginx -c [conf_file]
有時候在開啟一些服務時 如Certbot
他會很熱心的幫你把nginx打開
但這時就會跟 systemctl 的開法衝突
然後就會爛掉 要用這種方法把nginx關掉
或是直接kill 簡單快速方便
目標:將社網部署到伺服器上
要求:
提示:
1. 社網在這裡(為啥 27th? 因為 react 太麻煩)
2. 如何遠端複製檔案到 server? 用 scp
3. 可以 google:nginx static site 試試看
4. 如果你要 https ,可以用看看 certbot,但今天沒網址給你試
5. 如何檢視電腦 ip?用 hostname -I 看
拉取 ubuntu image
docker image pull ubuntu
查看 image list
docker image list
成立一個 container 並且執行指令
# 產生一個 ubuntu 並且輸出 Hello world
sudo docker run ubuntu /bin/echo 'Hello world'
# 產生一個 ubuntu 並且進入 bash
sudo docker run --name test ubuntu "/bin/bash"
# 查看現有的 container
docker ps -a
對,沒錯
所以來介紹另一種建立 image 的方式 --- Dockerfile
實務上我們會從 Docker Hub 下載官方的 Docker Image 使用,但官方的 image 功能可能過於陽春,我們可能想根據自己的需求,再安裝其他的 app,最後再打包成自己的 Docker image
FROM: 映像檔基底 像是 ubuntu 或是有內建一些東西的nginx node
VOLUME: 在不同的執行階段保存檔案
WORKDIR: 指定之後的 RUN/CMD/ENTRYPOINT/COPY之根目錄
COPY: 從原本路徑複製一份到image裡面的新路徑中 常用 COPY . RUN: 執行指令
EXPOSE: 揭露某一個特定端口給原本的電腦連接
ENTRYPOINT: CMD的前置作業
CMD: 由image建立container時執行的指令
等下會更詳細介紹 先來看 Dockerfile 架構
FROM ubuntu:latest #抓取預設映像檔
VOLUME /data #使 /data 跨工作階段保存
WORKDIR /data #指定在 /data 工作
COPY . . #將現有的東西複製進去
RUN apt install -y neofetch
# 注意 -y 很重要 不然 apt 會跳prompt
# 它會讓你永遠install不完
RUN whatever you want
# 記得不要有會等待的東西就好
EXPOSE 3000
# 向外部開啟3000口(通常做測試用)
CMD ["rails", "s"]
# 啟動服務 這時如果這個指令停下整個container也會停下
# 所以通常是放 node server.js / rails s 之類的東西
背景
設定
轉移資料
做正事
做完叫大家來看
啟動跟大家分享
照這個做基本上不會出甚麼大事
但要注意有時候有些東西也不是必需的
有些則可以直接寫在等下要講的 docker compose
回來講那些指令怎麼用
分開來講 先後順序問題回去看上面
指定基礎image 寫在第一行
FROM 基礎image:版本
像是
FROM node:20
版本也可以直接寫 latest
FROM ubuntu:latest
在不同執行階段間固定一些文件
像是你希望 /data 不要被洗掉
VOLUME dir
VOLUME [dirs...]
也可以一次寫很多個
VOLUME /data
VOLUME ["/data1", "/data2"]
其實我不常用 大多時候直接在compose寫
使接下來的 CMD / RUN / ENTRYPOINT / COPY
會發生在你指定的地方
WORKDIR dir
好像沒什麼好講的
例
WORKDIR /data
這個copy比較酷一點
COPY original_file file_in_image
他會把你現在這個Dockerfile所在的檔案系統的東西
根據你的設定塞進你要創建的image當中
並放在後者的路徑上 建議使用絕對路徑
例
COPY app/ /data/app
注意 / 的使用
對於後者
如果是 /data/
代表 data 是一個資料夾 你要把前述東西放進去
如果是 /data/app
代表 app 是一個檔名 你要把前述東西命名為app並放到data裡面
COPY app/ /data/app
也有很多人直接
COPY . .
COPY . .
全部砸進去 誰管他
就執行一個 cli 命令阿
RUN command
唯一要注意的是不能讓他跳出選擇畫面
不然永遠跑不完
最常見的就是apt install要加 -y
其它自己查
RUN apt install -y neofetch
就打開一個port阿
EXPOSE port
阿對就這樣
但也不常用 在compose設定就好
EXPOSE 3000
可以幫你在正式開啟服務前做些事情
ENTRYPOINT ["command"...]
為甚麼不用 RUN: 那些東西在build時就跑完了
為甚麼不用 CMD: 太正式了 要先準備一下
通常會寫一個 shell script 去跑
ENTRYPOINT ["docker-setup.sh"]
沒用過
最終站
CMD ["command"...]
啟動最終程式
如果這個程式只跑一下就跑完了或是以daemon開啟就會直接關掉container
所以通常是用啟動伺服器的指令放在這裡
CMD ["rails", "s"]
有空格的話就要分開
話說我很久以前說我要來幹訓傳教 Ruby on Rails
為甚麼現在在講SA
好懶得做簡報喔 by AaW in 2024
害我做簡報好累
來看看例子
FROM ubuntu:latest
# Install Linux library dependency
RUN apt-get update
RUN apt-get install -y wget apt-transport-https gpg
# Install microsoft.gpg
RUN wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
RUN mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
RUN wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
RUN mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
RUN chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
RUN chown root:root /etc/apt/sources.list.d/microsoft-prod.list
# Install .NET Core SDK
RUN apt-get update
RUN apt-get install -y dotnet-sdk-2.1
# Display Greeting
CMD [ "echo", "Ubuntu 18.04 LTS with .NET Core 2.1"]
來看看例子
CMS Dockerfile by 成大某位電神
FROM ubuntu:20.04
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y \
build-essential \
cgroup-lite \
cppreference-doc-en-html \
fp-compiler \
git \
haskell-platform \
libcap-dev \
libcups2-dev \
libffi-dev \
libpq-dev \
libyaml-dev \
mono-mcs \
openjdk-8-jdk-headless \
php7.4-cli \
postgresql-client \
python3-pip \
python3.8 \
python3.8-dev \
rustc \
sudo \
wait-for-it \
zip \
vim
# Create cmsuser user with sudo privileges
RUN useradd -ms /bin/bash cmsuser && \
usermod -aG sudo cmsuser
# Disable sudo password
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# Set cmsuser as default user
USER cmsuser
COPY --chown=cmsuser:cmsuser . /home/cmsuser/cms
WORKDIR /home/cmsuser/cms
EXPOSE 8888-8890
RUN sudo pip3 install -r requirements.txt
RUN sudo pip3 install -r dev-requirements.txt
RUN sudo python3 setup.py install
RUN sudo python3 prerequisites.py --yes --cmsuser=cmsuser install
RUN sudo sed 's/cmsuser:0000@localhost/postgres@db/' ./config/cms.conf.sample \
| sudo tee /usr/local/etc/cms.conf
ENV LANG C.UTF-8
CMD [""]
基本上 RUN 開頭的東西都是 CMS doc 裡面的安裝指令
使用這個指令可以把一個Dockerfile編譯成image
image name的設定是為了之後方便啟動
build dir 則是指定你的Dockerfile在哪個資料夾
通常使用 . 即可
docker build -t image_name build_dir
docker build -t nasa2025 .
把 image 啟動成 container 並開啟
這樣就開始跑了 但有一些常用的flag
docker run image_name
docker run -it image_name bash
這可以開起來並且連接一個shell進container
並使用bash
連接shell進一個container
docker exec -it container_name bash
列出所有container
把一些build完但不需要用到的image刪除
如果你亂build然後沒空間可能要用
docker ps -a
docker images
列出所有image
docker system prune
舊版 docker compose 使用之指令為
docker-compose
新版為
docker compose
可是,有些時候,一個 Container 沒辦法完成所有事情
一個指令,自動根據規則
完成 build image、啟動多個 container
並且操控多個 container
docker-compose.yml 就是 container 的管理文件,只是採用 code 形式描述
docker-compose.yml
文件中。看看例子
version: '3'
services:
web:
image: my-web-app:latest
ports:
- "5000:5000"
depends_on:
- redis
redis:
image: redis:alpine
總共有兩個 container
一個 Web 服務和一個 Redis 服務
image: 從哪裡抓 image
volumes: 映射資料夾進去容器
environment: 傳送變數
ports: 映射通訊阜口
看看例子
version: "3.7"
x-logging:
&default-logging
driver: "json-file"
options:
max-size: "100m"
max-file: "2"
services:
web:
build:
context: ./
args:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
TIOJ_KEY: $FETCH_KEY
environment:
- RAILS_ENV=production
- SMTP_USERNAME
- SMTP_PASSWORD
- SMTP_PORT
- SMTP_ADDRESS
- MAIL_HOSTNAME
- MAIL_SENDER
volumes:
- /srv/tioj/web-td:/tioj/td
- /srv/tioj/web-log:/tioj/log
- /srv/tioj/public:/tioj/public
depends_on:
- db
networks:
- app
ports:
- "4000:4000"
logging: *default-logging
db:
image: mysql:8.0
volumes:
- /srv/tioj/db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE=tioj_production
networks:
- app
logging: *default-logging
judge:
build: https://github.com/TIOJ-INFOR-Online-Judge/tioj-judge.git#ddb2f430eb7b6a4561ed23c1ef2ad94fcafc5b22
environment:
TIOJ_URL: "http://localhost:4000"
TIOJ_KEY: $FETCH_KEY
volumes:
- /srv/tioj/judge-td-pool:/var/lib/tioj-judge/td-pool
- /srv/tioj/judge-testdata:/var/lib/tioj-judge/testdata
tmpfs:
- /tmp:exec
privileged: true
network_mode: host
pid: host
logging: *default-logging
networks:
app:
總共有三個 container
image: 從哪裡抓 image
web: 直接編譯 dockerfile
db: 從 docker hub 抓 image
judge: 從另一個github repo 的 dockerfile 編譯
volumes: 映射資料夾進去容器
environment: 傳送變數
ports: 映射通訊阜口
看看例子
version: "3"
services:
oj-redis:
image: redis:4.0-alpine
container_name: oj-redis
restart: always
volumes:
- ./data/redis:/data
oj-postgres:
image: postgres:10-alpine
container_name: oj-postgres
restart: always
volumes:
- ./data/postgres:/var/lib/postgresql/data
environment:
- POSTGRES_DB=onlinejudge
- POSTGRES_USER=onlinejudge
- POSTGRES_PASSWORD=onlinejudge
judge-server:
image: registry.cn-hangzhou.aliyuncs.com/onlinejudge/judge_server
container_name: judge-server
restart: always
read_only: true
cap_drop:
- SETPCAP
- MKNOD
- NET_BIND_SERVICE
- SYS_CHROOT
- SETFCAP
- FSETID
tmpfs:
- /tmp
volumes:
- ./data/backend/test_case:/test_case:ro
- ./data/judge_server/log:/log
- ./data/judge_server/run:/judger
environment:
- SERVICE_URL=http://judge-server:8080
- BACKEND_URL=http://oj-backend:8000/api/judge_server_heartbeat/
- TOKEN=CHANGE_THIS
# - judger_debug=1
oj-backend:
image: registry.cn-hangzhou.aliyuncs.com/onlinejudge/oj_backend
container_name: oj-backend
restart: always
depends_on:
- oj-redis
- oj-postgres
- judge-server
volumes:
- ./data/backend:/data
environment:
- POSTGRES_DB=onlinejudge
- POSTGRES_USER=onlinejudge
- POSTGRES_PASSWORD=onlinejudge
- JUDGE_SERVER_TOKEN=CHANGE_THIS
- FORCE_HTTPS=1
# - STATIC_CDN_HOST=cdn.oj.com
ports:
- "0.0.0.0:8000:8000"
- "0.0.0.0:1443:1443"
# 啟動服務
docker-compose up
# 在背景執行
docker-compose up -d
# 停止服務
docker-compose down
要求:
提示關鍵字:
docker nginx static
docker compose nginx static
這個錯誤如何 google ?
如何在 stackoverflow 問問題
用壞伺服器的道歉信 by AaW
雪溱老師您好:
我是建中電研的學術長吳亞倫,也是先前負責管理網頁伺服器的同學。
首先,我要對不慎刪除伺服器當中設定檔一事,向老師道歉。
當初7/30日時,當時虛擬機器被重啟之後,網站docker的啟動出了問題。但是,當我連線到伺服器時卻發覺伺服器的port被別的東西佔用了,導致我無法按照說明文件的方式啟用網站。而當時學長也不清楚伺服器的現況,但因為我太心急要處理暑訓的東西,因此便自己試著要嘗試解決,因此嘗試了一些網路上的做法,也因此可能不慎動到了不該動到的地方。最後我是將systemctl的nginx停掉之後才得以正常啟動網站。後來網站也一直以此方式運作到九月多。
對於此自行修理一事我感到非常的抱歉。我應該要在交接伺服器使用權之後便主動向老師您聯絡,並且了解伺服器的狀態。但是我卻反而單獨聽信網路上的說明文件與指令胡亂嘗試,才動到不該動的地方,造成了老師以及北資同學的麻煩。
其實,在老師將伺服器關機的這一段時間內,我一直對於此事感到十分的自責,同時,我也花了許多時間去研究伺服器相關的知識以及相同問題的處理方式,希望能夠挽救回伺服器,也為我闖的禍負責。
因此,我希望老師可以答應我的請求,讓我一同參與接下來伺服器修理或是轉移到新伺服器的工作,讓我有一次彌補過錯的機會,並且從老師的教導當中學習更多。我保證我皆會在經過老師允許之後才對伺服器進行修理及調整。
另外,為了避免再犯相同錯誤,我會詳細的紀錄下此修理過程,並且在明年詳細的交接給學弟妹,避免他們和我犯下一樣的錯誤。
此外,我也懇求老師能夠將原本伺服器暫時開機,讓我將原本的題目等資料備份下來,使得學弟妹能夠暫時以其他方式進行練習。
我知道我的錯誤使得老師十分生氣,實在不應該再提出這種請求。但是我非常希望能夠彌補我的錯誤,因此誠心希望老師能夠同意讓我協助北資的同學一起進行之後的修理工作。希望老師願意原諒我的錯誤。
以下是我的聯絡資訊:
email: xxxxxxxxxx
line ID: xxxxxxxxxxxx
希望能夠收到老師您的回覆
Sincerely,
吳亞倫 敬上
難以想像這是在GPT出現之前用手寫的
By cjtsai