Docker筆記

2018/05/28

安裝

官方文件:https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce

這邊介紹官方的快速安裝方式(Install using the convenience script)

使用curl下載安裝的shell script再執行即可

不過官方文件也有提到建議不要在production環境使用此方式安裝

並且應該了解一些潛在安全性風險

不過如果是開發環境為了方便我是就直接使用

 

Dockerfile

用來建立docker image的檔案

常用Dockerfile屬性

# Image
FROM node:8

# Container環境變數
ENV NODE_VERSION=8.11.0

# 使用RUN執行shell script
RUN pwd

# 透過${ENV_VARIABLE}來使用環境變數
RUN echo "NODE_VERSION -> ${NODE_VERSION}" >> foo.txt

# 對外開放port
EXPOSE 3000 80

# 每次Container被啟動時執行的指令
# 使用tail -f /dev/null避免一啟動container就自動關閉
CMD ["sh", "-c", "echo ${NODE_VERSION} && tail -f /dev/null"]

 

更多Dockerfile參考說明

 

常用Image操作

建立Image

# 使用目前目錄的Dockerfile下建立Image
docker build . 

# 建立Image時順便賦予tag方便後續操作
docker build --tag some-image . 

# 建立Image時賦予參數
docker build --tag some-image --build-arg MYSQL_ROOT_PASSWORD=123456 --build-arg FOO=bar .

# 建立Image時不使用cache
docker build --tag some-image . --no-cache

 

啟動Image建立Container

# 透過some建立container
docker run some-image

# 建立container時賦予名稱方便後續操作
docker run --name demo-container some-image

# 建立container後使用detach模式(在背景執行, 不會直接進入container)
docker run -p 3000:3000 -p 81:80 -d some-image

# 建立container時mapping port到實體主機
docker run -p 3000:3000 -p 81:80 some-image

# 建立container時指定volumes
docker run -v /your-host/some-folder:/storage --name demo-container some-image

 

移除所有<none>的image

docker images -f 'dangling=true' -q就是透過filter(-f)找出none的image id

docker rmi (docker images -f 'dangling=true' -q)

 

常用Container操作

移除所有container

docker ps -a -q就是找出全部的container id

docker rm (docker ps -a -q)

 

進入某個container

docker exec -it [container-id/container-name] bash

 

對某個container執行command但不進入

docker exec -it [container-id/container-name] apt-update

 

Docker Compose

雖然Dockerfile可以直接建立Image、Container

但是管理多個Image、Container的時候就會變得不太方便

因此可以透過Docker Compose的service來管理多個Image

只要建立一個docker-compose.yml檔案

就可以一次管理多個Image

 

以此docker-compose.yml為例

只要這樣就能快速建立一個adminer+mysql的服務

version: "3"
services:
  admin:
    image: adminer
    ports:
      - 8080:8080
    depends_on:
      - db
    links:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456

更多docker-compose.yml參考文件

 

常用Docker Compose操作

# 列出所有docker-compose建立的container
docker-compose ps

# 建立image並不使用cache
docker-compose build --no-cache

# run services並強制build image
docker-compose up --build

# 使用detach模式
docker-compose up --d

# 刪除所有docker-compose建立的container
docker-compose down

# 刪除所有docker-compose建立的container, 並連同相關的volume一併刪除
docker-compose down --volume

 

一些一開始搞錯的用法

 

在Dockerfile中使用docker-compose.yml的變數

這是發生在我使用docker-compose.yml建立mysql服務的情境下

一開始以為在Dockerfile中使用ENV屬性就可以吃到docker-compose.yml中的環境變數(mysql的密碼)

結果後來裝完mysql發現裝完都吃到密碼

才知道在docker-compose.ymlDockerfile中都要使用ARG屬性來傳變數

最後在Dockerfile中再將接到的ARG變數assign到ENV中使用

大致情況如下

 

.env

MYSQL_ROOT_PASSWORD=1234

 

docker-compose.yml

version: "3"
services:
  backend:
    container_name: backend
    env_file:
      - .env
    build:
      context: ./backend
      args:
        - MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
    ports:
      - 81:80

 

./backend/Dockerfile

FROM ubuntu:16.04
MAINTAINER Ciao Chung

ARG MYSQL_ROOT_PASSWORD
ENV MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}

### 其他不重要的都省略

# mysql
RUN apt-get update
RUN echo "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PASSWORD}" | debconf-set-selections
RUN echo "mysql-server mysql-server/root_password_again password ${MYSQL_ROOT_PASSWORD}" | debconf-set-selections
RUN apt-get install mysql-server-5.7 -y && mysql --version

### 其他不重要的都省略