參考
環境
- Centos 7.6 #未安裝Centos7,可以參考這篇文章
- Docker 1.13.1
步驟
yum -y install docker
國內源
官方中國區:https://registry.docker-cn.com
網易:http://hub-mirror.c.163.com
阿里云:教程參考網址
進入阿里云:https://cr.console.aliyun.com/#/accelerator
獲取你自己的加速地址,獲取地址后與其他源的步驟一樣如下:
#更換docker鏡像源
vi /etc/docker/damen.json
#如果沒有damen.json,則新建
{"registry-mirrors": ["加速鏡像地址"]}
systemctl daemon-reload#重啟生效源
systemctl start docker#啟動docker
systemctl status docker#docker狀態
systemctl enable docker#開機啟動docker
docker version#查看docker版本
docker info #查看docker信息
下載docker鏡像
docker search centos #查找centos鏡像
docker pull docker.io/centos# 拉取鏡像
docker images #查看鏡像
docker search tomcat
docker pull docker.io/tomcat
# docker pull hub.c.163.com/library/tomcat:latest #拉取tomcat
docker stop $(docker ps -a -q) #停止所有鏡像
docker rm $(docker ps --all -q -f status=exited) # 刪除所有停止
docker rmi `docker images -q` # 刪除所有鏡像
docker images | grep tomcat
# 開啟網絡轉發功能,默認自動開啟
# 手動開啟
vi /etc/sysctl.conf #插入一句話:
net.ipv4.ip_forward=1
sysctl -p #生效
cat /proc/sys/net/ipv4/ip_forward # 返回1
#關閉防火墻
systemctl stop firewalld
systemctl status firewalld
systemctl restart docker
iptables -L
# 查看docker可以運行的端口
docker平臺基本使用方法
- 運行Centos,執行/bin/bash/命令
run 運行
-i 以交互模式運行容器,通常與-t同時使用
-t 為容器重新分配一個偽終端,通常與-i 同時使用
docker run -it docker.io/centos:latest /bin/bash
# 進入容器內
ls
cat /etc/redhat-release# 查看版本
exit # 退出容器/ctrl +a+d
- 在容器中啟動一個長久運行的進程,不斷向stdin輸出hello world,模擬一個后臺運行的服務
docker run -d docker.io/centos:latest /bin/sh -c "while true;do echo hello world;sleep 1;done"
docker ps
docker logs 容器ID -f # 489ecb60578e容器ID可以寫全,也可以不寫全只要唯一就可以 -f 實時輸出
docker kill 容器ID == docker stop 容器ID #關閉容器
docker rm 容器ID #s刪除容器
docker ps -a # 查看所有運行的容器
docker stop 62e #容器少就可以簡寫三位,多則寫6位
docker ps -a
docker rm 62e
docker rm edf
docker ps -a
容器啟動關閉等命令
命令 | 解釋 |
---|---|
docker stop 容器ID | #關閉容器 |
docker start 容器ID | #啟動容器 |
docker restart 容器ID | #重啟容器 |
docker rm 容器ID | #刪除指定容器 |
docker鏡像制作方法:
- docker commit #保存container的當前狀態到image后,然后生成對應的image
- docker build #使用Dockerfile文件自動化制作image
(1) docker commit
docker run -it docker.io/centos:latest /bin/bash
yum -y install httpd #安裝apache
exit #退出
docker images
docker ps -a
#獲取容器ID 13d52db82f63
docker commit 13d52db82f63 xuegod/apache:apache #命名:TAG
docker images
# 可以看到xuegod/apache(容器名字) apache(TAG內容)
docker run -it xuegod/apache:apache /bin/bash
rpm -qa httpd #查看apache是否安裝
exit
docker run -itd -p 9090:80 xuegod/apache:apache /bin/bash
# -p是宿主機端口號:容器端口號
ifconfig
eth32:為宿主機網絡地址192.168.45.141
curl 宿主機網絡地址
# 被拒絕
docker ps -a
# 查看容器ID beb78d3ffccd
docker inspect 容器ID # 查看容器配置
# IPAdress:"IP地址" 172.17.0.2
docker exec -it 容器ID /bin/bash #進入開啟的容器
systemctl start httpd# 失敗
cd /etc/init.d/
ls
lsof -i #失敗
find ./ -name "*apache*"
# /usr/sbin/httpd -h
/usr/sbin/apachectl -h
/usr/sbin/apachectl #開啟apache
ps aux|grep apache
ctrl a+d
curl apache容器IP:80# 172.17.0.2
# 使用宿主機IP
ifconfig
docker ps -a
curl 宿主機IP:9090 #也可以訪問
# Container容器端口映射
# 啟動容器
docker run -d -p 80:80
# -p 物理機的80端口:容器的80端口,把容器的80端口映射到物理機上的80端口
docker help
# attach進入容器
# cp拷貝文件到容器中
# creation創建容器
# 宿主機新建a.txt,內容隨便填一些
docker cp /home/a.txt 容器ID:/home # beb78d3ffccd
docker exec -it 容器ID /bin/bash
# docker 容器獲取root權限
docker rm 容器ID #刪除容器
docker rmi 鏡像ID#刪除鏡像
docker image prune #刪除懸掛鏡像
dockerfile的基本使用:
Dockerfile基本講解
制作python運行的uwsgi環境+django
Dockerfile基本講解
cd /home
ls
mkdir xuegod
ls
cd xuegod
ls
vim Dockerfile
FROM nginx
RUN echo "<h1>Hello Docker</h1>" > /usr/share/nginx/html/index.html
docker build -t mynginx:v1 .
docker run -itd -p 8080:80 mynginx:v1
瀏覽器輸入宿主機IP:8080訪問
FROM: 指定鏡像基礎(MANITARNER 作者信息)
所謂的定制鏡像,那一定是一個鏡像為基礎就,在其上進行定制。就像我們之前運行了一個nginx鏡像的容器,再次進行修改一樣,基礎鏡像必須指定。而from就是指定基礎鏡像,因此一個Dockerfile中的from是必備指定,而且必須是第一條指令。
在docker store上有很多的高質量的官方鏡像,可以直接拿來使用的服務類鏡像如:nginx,redis,mongo,mysql,httpd,php,tomcat等,也有一些方便開發構建運行各種語言應用的鏡像如node,openjdk,python,ruby,golang等。可以在其中尋找符合我們最終目標的鏡像為基礎鏡像(official)。
如果沒有找到對應的服務鏡像,官方鏡像中還提供了一些更為基礎的操作系統鏡像,如ubuntu、debain、centos、fedora、alpine等,這些操作系統的軟件庫為我們提供了更廣闊的空間。
除了選擇現有的鏡像為基礎鏡像外,docker還存在一個特殊的鏡像,名為scratch。這個鏡像是虛擬的概念,并不實際存在,她表示一個空白鏡像。
如果你以scratch為基礎鏡像,意味著你不以任何鏡像為基礎,接下來所寫的指令作為鏡像第一層開始存在。
不以任何系統為基礎,直接將可執行文件復制到鏡像的做法并不罕見,如swarm,coreos/etcd。對于linux下的靜態編譯的程序來說,并不需要有操作系統的提示運行時支持,所需的一切庫都已經在可執行文件里面了,因此直接from scratch會讓鏡像體積更小巧。使用go語言開發的應用很多會使用這種方式制作鏡像,這也是為什么有人認為go特別適合容器微服務架構的語言之一。
docker使用go long語言編寫
run 執行指令
run 指令是用來執行命令行的命令,由于命令行的強大能力,run指令在指定鏡像是是最常用的指令之一。兩種格式。
- shell格式 run <命令>就像直接在命令行中輸入一樣。
- exec格式,run ["可執行文件","參數一","參數二"],這更像函數調用中的格式
可以有多個run,cmd只能一個
既然run像shell腳本一樣可以執行命令,那么我們是否就可以像shell腳本一樣把每個命令對應一個run呢?
FROM debain:jessie
RUN apt-get update
RUN apt-get install gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"
....
第二種:
FROM debian:jessie
RUN buildDeps='gcc libc6-dev make'
&& apt-get update
&& apt-get install -y $buildDeps
&& wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"
....
mkdir d1
cd d1
vim Dockerfile
FROM debain:jessie
RUN apt-get update
RUN apt-get install gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"
docker build -t myredis:v1 .
# step 1/4
mkdir d2
cd d2
vim Dockerfile
FROM debian:jessie
RUN buildDeps='gcc libc6-dev make'\
&& apt-get update \
&& apt-get install -y $buildDeps\
&& wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"
mv Dockerfile xuegod_dockerfile
docker build -t myredis:v2 -f /homexuegod_dockerfile .
# step 1/2
copy 復制文件
格式:
COPY [--chown=<user>:<group>]<源路徑(宿主機路徑)>...<目標路徑(容器內路徑)>
COPY [--chown=<user>:<group>]['<源路徑>'...'<目標路徑>']
vim a.json
#隨便輸入
vim Dockerfile
FROM nginx #拉去鏡像
COPY a.json /home
docker build -t myredis:v3 .
docker run -it myredis:v3 /bin/bash
ls
cd /home
ls
# a.json
<源路徑>可以是多個,甚至可以是通配符,其通配規則要滿足GO的filepath.Match規則,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目標路徑>可以是容器內的絕對路徑,也可以是相對于工作目錄的相對路徑,工作目錄可以用WORLDIR指令來指定。目標路徑不需要事先創建,如果目錄不存在會在復制文件前先行創建缺失目錄。
ADD更高級的復制文件
ADD 更高級的復制文件ADD指令和COPY的格式和性質基本一致。但是在COPY基礎上增加了一些功能。比如<源路徑>可以是一個URL,這種情況下,Docker 引擎會試圖去下載這個鏈接的文件放到<目標路徑>去。下載后的文件權限自動設置為600,如果這并不是想要的權限,那么還需要增加額外的一層RUN進行權限調整,另外,如果下載的是個壓縮包,需要解壓縮,也一樣還需要額外的一層RUN指令進行解壓縮。所以不如直接使用RUN指令,然后使用wget或者curl工具下載,處理權限、解壓縮、然后清理無用文件更合理。因此,這個功能其實并不實用,而且不推薦使用。如果<源路徑>為一個tar壓縮文件的話,壓縮格式為gzip, bzip2以及xz的情況下,ADD指令將會自動解壓縮這個壓縮文件到<目標路徑>去。
CMD 容器啟動命令
CMD指令的格式和RUN相似,也是兩種格式:
shell格式:CMD <命令>
exec格式:CMD ["可執行文件", "參數1", "參數2"...]
例如: CMD ["nginx","-g","daemon","off;"]
參數列表格式:CMD ["參數1", "參數2"...]。在指定了ENTRYPOINT指令后,用CMD指定具體的參數。
之前介紹容器的時候曾經說過,Docker 不是虛擬機,容器就是進程。既然是進程,那么在啟動容器的時候,需要指定所運行的程序及參數。CMD指令就是用于指定默認的容器主進程的啟動命令的。在運行時可以指定新的命令來替代鏡像設置中的這個默認命令,比如,ubuntu鏡像默認的CMD是/bin/bash,如果我們直接docker run -it ubuntu的話,會直接進入bash。我們也可以在運行時指定運行別的命令,如dockerrun -it ubuntu cat /etc/os-release。這就是用cat /etc/os-release命令替換了默認的/bin/bash命令了,輸出了系統版本信息。在指令格式上,一般推薦使用exec格式,這類格式在解析時會被解析為 JSON數組,因此一定要使用雙引號",而不要使用單引號。
docker run -it ubuntu #進入bash
dockerrun -it ubuntu cat /etc/os-release #輸出系統信息
CMD ehco HOME" ]
提到CMD就不得不提容器中應用在前臺執行和后臺執行的問題.
Docker 不是虛擬機,容器中的應用都應該以前臺執行,而不是像虛擬機、物理機里面那樣,用 upstart/systemd 去啟動后臺服務,容器內沒有后臺服務的概念。一些初學者將CMD寫為:CMDservice nginx start然后發現容器執行后就立即退出了。甚至在容器內去使用systemctl命令結果卻發現根本執行不了。這就是因為沒有搞明白前臺、后臺的概念,沒有區分容器和虛擬機的差異,依舊在以傳統虛擬機的角度去理解容器。
對于容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。
而使用service nginx start命令,則是希望 upstart 來以后臺守護進程形式啟動nginx服務。而剛才說了CMD service nginx start會被理解為CMD ["sh", "-c", "service nginx start"],因此主進程實際上是sh。那么當service nginx start命令結束后,sh也就結束了,sh作為主進程退出了,自然就會令容器退出。正確的做法是直接執行nginx可執行文件,并且要求以前臺形式運行。比如:CMD["nginx", "-g", "daemon off;"]
vim Dockerfile
FROM nginx
CMD ["sh", "-c", "service nginx start"]
docker build -t mynginx:v5 .
docker run -it nginx:v5
docker ps -a
#v5容器退出
vim Dockerfile
FROM nginx
CMD ["ngnix", "-g", "daemon off;"]
# -g前臺運行 daemon off關閉守護進程
docker build -t mynginx:v6 .
docker run -itd nginx:v6
docker ps -a
#v6容器運行中
docker logs 容器ID
docker restart 容器v6ID
ENTRYPOINT 入口點
ENTRYPOINT的格式和RUN指令格式一樣,分為exec格式和shell格式。ENTRYPOINT的目的和CMD一樣,都是在指定容器啟動程序及參數。
ENTRYPOINT在運行時也可以替代,不過比CMD要略顯繁瑣,需要通過docker run的參數--entrypoint來指定當指定了ENTRYPOINT后,CMD的含義就發生了改變,不再是直接的運行其命令,而是將CMD的內容作為參數傳給ENTRYPOINT指令,換句話說實際執行時,將變為:<ENTRYPOINT> "<CMD>"
那么有了CMD后,為什么還要有ENTRYPOINT呢?這種<ENTRYPOINT> "<CMD>"有什么好處么?讓我們來看幾個場景。
場景一:讓鏡像變成像命令一樣使用
假設我們需要一個得知自己當前公網 IP 的鏡像,那么可以先用CMD來實現:
vim Dockerfile
FROM ubuntu:18.04
RUN apt-get update\
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
CMD ["curl","-s","https://ip.cn"]
# http://ifconfig.me
docker build -t myip .
docker run myip
嗯,這么看起來好像可以直接把鏡像當做命令使用了,不過命令總有參數,如果我們希望加參數呢?比如從上面的CMD中可以看到實質的命令是curl,那么如果我們希望顯示 HTTP 頭信息,就需要加上-i參數。那么我們可以直接加-i參數給docker run myip么?
docker run myip -i
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"-i\\\": executable file not found in $PATH\"\n".
我們可以看到可執行文件找不到的報錯,executable file not found。之前我們說過,跟在鏡像名后面的是command,運行時會替換CMD的默認值。因此這里的-i替換了原來的CMD,而不是添加在原來的curl -shttps://ip.cn后面。而-i根本不是命令,所以自然找不到。
那么如果我們希望加入-i這參數,我們就必須重新完整的輸入這個命令:
docker run myip curl -s https//ip.cn -i
這顯然不是很好的解決方案,而使用ENTRYPOINT就可以解決這個問題。現在我們重新用ENTRYPOINT來實現這個鏡像:
vim Dockerfile
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT[ "curl", "-s", "https://ip.cn" ]
# 加-i視為追加命令
docker build -t myip:v3 .
docker run myip:v3 -i
可以看到,這次成功了。這是因為當存在ENTRYPOINT后,CMD的內容將會作為參數傳給ENTRYPOINT,而這里-i就是新的CMD,因此會作為參數傳給curl,從而達到了我們預期的效果。
ENV 設置環境變量
格式有兩種:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
這個指令很簡單,就是設置環境變量而已,無論是后面的其它指令,如RUN,還是運行時的應用,都可以直接使用這里定義的環境變量。
ENV VERSION=1.0 DEBUG=on \
NAME="Happy Feet"
這個例子中演示了如何換行,以及對含有空格的值用雙引號括起來的辦法,這和Shell 下的行為是一致的。
定義了環境變量,那么在后續的指令中,就可以使用這個環境變量。
比如在官方node鏡像Dockerfile中,就有類似這樣的代碼:
ENV NODE_VERSION 7.2.0
RUNcurl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
在這里先定義了環境變量NODE_VERSION,其后的RUN這層里,多次使用$NODE_VERSION來進行操作定制。可以看到,將來升級鏡像構建版本的時候,只需要更新7.2.0即可,Dockerfile構建維護變得更輕松了。
VOLUME 定義匿名卷
VOLUME 定義匿名卷格式為:
VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>
之前我們說過,容器運行時應該盡量保持容器存儲層不發生寫操作,對于數據庫類需要保存動態數據的應用,其數據庫文件應該保存于卷(volume)中,后面的章節我們會進一步介紹 Docker 卷的概念。為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在Dockerfile中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。
VOLUME/data
這里的/data目錄就會在運行時自動掛載為匿名卷,任何向/data中寫入的信息都不會記錄進容器存儲層,從而保證了容器存儲層的無狀態化。當然,運行時可以覆蓋這個掛載設置。比如
docker run -d -v mydata:/data xxxx
在這行命令中,就使用了mydata這個命名卷掛載到了/data這個位置,替代了Dockerfile中定義的匿名卷的掛載配置。掛載到宿主機
EXPOSE 聲明端口
格式為EXPOSE <端口1> [<端口2>...]。
EXPOSE指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務。在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;另一個用處則是在運行時使用隨機端口映射時,也就是docker run -P時,會自動隨機映射EXPOSE的端口。要將EXPOSE和在運行時使用-p <宿主端口>:<容器端口>區分開來。-p,是映射宿主端口和容器端口,換句話說,就是將容器的對應端口服務公開給外界訪問,而EXPOSE僅僅是聲明容器打算使用什么端口而已,并不會自動在宿主進行端口映射。
WORKDIR 指定工作目錄
格式為WORKDIR <工作目錄路徑>。
使用WORKDIR指令可以來指定工作目錄(或者稱為當前目錄),以后各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR會幫你建立目錄。之前提到一些初學者常犯的錯誤是把Dockerfile等同于 Shell 腳本來書寫,這種錯誤的理解還可能會導致出現下面這樣的錯誤:
RUN cd /app
# WORKDIR /var/log 正確的
RUN echo"hello" > world.txt
如果將這個Dockerfile進行構建鏡像運行后,會發現找不到/app/world.txt文件,或者其內容不是hello。原因其實很簡單,在 Shell中,連續兩行是同一個進程執行環境,因此前一個命令修改的內存狀態,會直接影響后一個命令;而在Dockerfile中,這兩行RUN命令的執行環境根本不同,是兩個完全不同的容器。這就是對Dockerfile構建分層存儲的概念不了解所導致的錯誤。之前說過每一個RUN都是啟動一個容器、執行命令、然后提交存儲層文件變更。第一層RUN cd /app的執行僅僅是當前進程的工作目錄變更,一個內存上的變化而已,其結果不會造成任何文件變更。而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器更完全沒關系,自然不可能繼承前一層構建過程中的內存變化。
USER 指定當前用戶
格式:USER <用戶名>[:<用戶組>]
USER指令和WORKDIR相似,都是改變環境狀態并影響以后的層。WORKDIR是改變工作目錄,USER則是改變之后層的執行RUN, CMD以及ENTRYPOINT這類命令的身份。當然,和WORKDIR一樣,USER只是幫助你切換到指定用戶而已,這個用戶必須是事先建立好的,否則無法切換。
當然,和WORKDIR一樣,USER只是幫助你切換到指定用戶而已,這個用戶必須是事先建立好的,否則無法切換。
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]
如果以root執行的腳本,在執行期間希望改變身份,比如希望以某個已經建立好的用戶來運行某個服務進程,不要使用su或者sudo,這些都需要比較麻煩的配置,而且在 TTY 缺失的環境下經常出錯。建議使用gosu。
# 建立 redis 用戶,并使用 gosu 換另一個用戶執行命令
RUNgroupadd -r redis && useradd -r -g redis redis
# 下載 gosu
RUNwget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
# 設置 CMD,并以另外的用戶執行
CMD[ "exec", "gosu", "redis", "redis-server" ]
實戰演示 -- 制作python運行的uwsgi環境+django+nginx
步驟一:制作django app
1.首先使用命令
# django-admin startproject xuegod
django-admin startapp xuegod
#沒學過django的可以理解為就是一些文件
xuegod/xuegod/settings.py
把ALLOWED_HOSTS =[]改為ALLOWED_HOSTS =["*"]
- 把xuegod app放到app/src目錄下
- 在app/src目錄下創建uwsgi.ini文件
uwsgi.ini
[uwsgi]
chdir = /var/www/src/xuegod
wsgi-file=/var/www/src/xuegod/xuegod/wsgi.py
master=true
processes=1
http= :8888
chmod-socket=666
vacuum=true
#logto=/var/www/src/test.log
#pidfile=/var/www/src/uswgi2.pid
# plugins=python
- 編寫依賴包requirements.txt
django
uwsgi
- 編寫Dockerfile
#基礎鏡像
FROM python:3.6-alpine3.8
RUN mkdir /var/www/
# 制定工作目錄相當于 cd /var/www/
WORKDIR /var/www
#設置時區和源
ENV TIME_ZONE Asia/Shanghai
#使用清華源
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main/" > /etc/apk/repositories
# 更新時區
RUN apk add --no-cache -U tzdata
&& ln -sf /usr/share/zoneinfo/{TIME_ZONE}" > /etc/timezone
#拷貝安裝python 包清單
COPY . ./
#第一個點 app下所有文件 第二個點/var/www
# app目錄下所有文件拷貝到/var/www
#項目依賴包
RUN apk update && apk add
bash
libuuid
pcre
mailcap
gcc
libc-dev
linux-headers
pcre-dev
alpine-sdk \安裝pandas,numpy依賴
&& python -m pip install --upgrade --force pip
&& pip install setuptools
&& pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
&& apk del
gcc
libc-dev
linux-headers
&& rm -rf /tmp/*
#切換工作目錄
WORKDIR /var/www/src
CMD ["/bin/bash","/var/www/run.sh"]
run.sh
#!/bin/bash
python /var/www/src/xuegod/manage.py makemigrations
python /var/www/src/xuegod/manage.py migrate
uwsgi --ini /var/www/uwsgi.ini
xshell中輸入rz(上傳)
把app打包,上傳到主機
uzip app.zip
cd app
ls
\# Dockerfile requirements.txt run.sh src uwsgi.ini
docker build -t xuegod/django:v1 .
#step 1/10
docker images
docker run -itd -p 8080:8888 xuegod/django:v1
docker ps -a
#正常應該是顯示運行了多長時間
主機IP:8080
實戰源代碼 (密碼:csjr)
筆記2