最近在把服務器上的應用盡量docker化,踩了不少坑……不過也正好學習docker
和docker-compose
的用法。此篇文章記錄docker常用命令、使用方法,用於備忘。
配置文件
主要是dockerfile
和docker-compose.yml
兩個文件,這倆的關係,簡單的講:
-
dockerfile
包含生成鏡像的配置信息,其中的指令作用的對象是鏡像。 -
docker-compose.yml
包含啓動容器的配置信息,其中指令作用的對象是容器。
鏡像一般只生成一次,而容器則可以啓動多個。
Dockerfile
用於生成docker鏡像的配置文件,簡單講就是初始化鏡像用的,比如拷貝文件到鏡像、執行命令、暴露端口、設置用戶等等。
生成鏡像的常用命令如下:
$ docker build -t name:tag PATH
docker build [OPTIONS] PATH | URL | -
通過
-t
指定鏡像名/版本
PATH
爲Dockerfile所在的目錄
格式
一個Dockerfile
大致長這個亞子:
FROM ubuntu
RUN useradd -m ctf
WORKDIR /home/ctf
COPY ./start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]
USER ctf
EXPOSE 9999
基本的書寫格式就是:指令+操作
使用
Dockerfile
生成鏡像,就是對原始鏡像逐步執行Dockerfile
中指令
指令
指令不多,列張表格好了:
指令 | 操作(例子) | 功能 |
---|---|---|
FROM | FROM ubuntu:16.04 |
指定初始鏡像 |
WORKDIR | WORKDIR /home/taqini |
切換工作目錄 |
USER | USER taqini |
切換默認用戶 |
ARG | ARG CODE_VERSION=latest |
定義變量 |
ENV | ENV DALAO=Imagin |
定義環境變量 |
COPY | COPY test /opt/test/ |
拷貝文件至鏡像 |
RUN | adduser taqini |
執行系統命令 |
EXPOSE | EXPOSE 80/tcp |
曝露端口 |
CMD | CMD ["start.sh"] |
啓動時執行命令 |
ENTERPOINT | ENTRYPOINT ["entrypoint.sh"] |
指定啓動時的入口點 |
FROM
指定初始鏡像( Base Image ),寫法有三種
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
一般直接FROM image:tag
就行
WORKDIR
相當於cd
,用於切換工作目錄,例如:
WORKDIR /dir
最後一個
WORKDIR
指定的路徑將作爲docker啓動的默認路徑
USER
切換到指定用戶,一般指定用戶名或是uid
:
USER taqini
USER 1001
默認用戶是root
ARG
用於定義臨時變量,例如:
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
ENV
設置環境變量,有兩種格式:
ENV <key> <value>
ENV <key>=<value> ...
使用等於號可以同時設置多個環境變量
COPY
從本地複製文件到鏡像,格式爲COPY 本地文件 目標鏡像文件
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
拷貝時可以使用相對路徑,前提是已經通過
WORKDIR
指定了工作目錄
COPY的同時修改文件所有者:
COPY --chown=user:group files* /somedir/
RUN
RUN就是執行系統命令,有兩種格式:
-
RUN <command>
(shell 格式) -
RUN ["executable", "param1", "param2"]
(exec 格式)
shell格式相當於把
RUN
後的command
依次作爲/bin/sh -c
的參數(子命令)exec格式則是直接執行括號中的命令
exec 格式使用的是
JSON
數組,所以只能用雙引號,不能用單引號!
一般使用第一種,例子:
RUN apt-get update
執行命令的默認用戶是root
第二種格式很麻煩,因爲它不會調用shell,所以環境變量什麼的就不會起作用,比如:
RUN [ "echo", "$HOME" ]
上面的用法是錯的,正確的用法應該是:
RUN [ "sh", "-c", "echo $HOME" ]
很麻煩是叭 _(:з」∠)
EXPOSE
配置曝露的端口
EXPOSE <port> [<port>/<protocol>...]
例如:
EXPOSE 80/tcp
曝露的端口用於在docker啓動時作端口映射,比如將docker的
80
端口映射到服務器的8080
端口:docker run -p 80:80/tcp ...
CMD
有三種寫法:
-
CMD ["executable","param1","param2"]
(exec 格式) -
CMD ["param1","param2"]
(用作ENTRYPOINT的參數) -
CMD command param1 param2
(shell 格式)
CMD指定的命令/腳本會在鏡像啓動時執行,是可執行容器默認的執行命令。
一個Dockerfile中只能有一個CMD指令,如果存在多個,則只有最後一個生效
ENTRYPOINT
鏡像啓動後的入口點。
和CMD不同,ENTRYPOINT先執行。
比如ENTRYPOINT指定了一個啓動腳本:
ENTRYPOINT ["entrypoint.sh"]
在鏡像啓動後,只會執行這個腳本的內容(即使Dockerfile
中有CMD指令)。
但是CMD指令也是有用處的,比如這樣:
CMD ["2333"]
ENTRYPOINT ["echo"]
運行鏡像的結果是:
2333
也就是說,如果之前有CMD指令,CMD指令的操作數其實是用作ENTRYPOINT的參數的。
如果不指定ENTRYPOINT,CMD的操作數就會被全部用作ENTRYPOINT的參數
所以看起來的效果就是默認執行了CMD
感覺沒說明白……文章末尾有參考文章,講的十分清楚(´•灬•‘)
LABLE
給鏡像添加標籤(沒啥用)
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
ADD
和COPY
差不多,但貌似只能在Linux下用,不提了。
VOLUME
用於創建鏡像內的掛載點,例如:
VOLUME ["/data"]
感覺沒啥用,一般操作是在
docker-compose
裏直接設置掛載點的信息
這篇先寫到這裏,docker-compose
的用法下一篇寫。