Docker入門筆記1

參考

  1. 嗶哩嗶哩
  2. 官方電子書

環境

  1. Centos 7.6 #未安裝Centos7,可以參考這篇文章
  2. 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 #查看鏡像
未安裝任何鏡像

安裝了Centos
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平臺基本使用方法

  1. 運行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
  1. 在容器中啟動一個長久運行的進程,不斷向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鏡像制作方法:

  1. docker commit #保存container的當前狀態到image后,然后生成對應的image
  2. 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指令在指定鏡像是是最常用的指令之一。兩種格式。

  1. shell格式 run <命令>就像直接在命令行中輸入一樣。
  2. 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[ "sh", "-c", "echoHOME" ]
提到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 =["*"]

  1. 把xuegod app放到app/src目錄下
  2. 在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

  1. 編寫依賴包requirements.txt

django
uwsgi

  1. 編寫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/localtime \ && echo "{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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375