实例1:Docker启动nginx,更改初始化界面


 

docker images 

列出所有镜像

 

docker run -p 14001:80 -d nginx

docker run 是基本命令,创建一个新的容器,后面可以跟命令,形如:docker run [OPTIONS] IMAGE [COMMAND] [ARG]

-p: 端口映射,格式为:主机(宿主)端口:容器端口

-d: 后台运行容器,并返回容器ID;

-i: 以交互模式运行容器,通常与 -t 同时使用;

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

--name=“nginx": 为容器指定一个名称,不指定会自己随机产生一个;

后面加上镜像名称,一般是选择镜像仓库中存在的镜像名称,如果选择仓库中不存在的镜像名称,则会默认从远端下载;

 

docker ps

列出所有正在运行的容器,首列是容器id

 

 

这个时候在主机输入localhost:14001应该可以看到nginx的欢迎界面

 

 

docker inspect a42409e14f6a

或者输入docker inspect gallant_kepler(docker ps返回的NAMES)

获取容器/镜像的元数据,这些元数据包含了很多容器信息,比如主机上储存文件的位置等等信息,比如获取正在运行的容器mymysql的 IP:

runoob@runoob:~$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mymysql

172.17.0.3

 

docker exec -it a42409e14f6a bash

进入容器内部查看,

-i :即使没有附加也保持STDIN 打开

-t :分配一个伪终端

 

which nginx 

查看nginx在什么位置上,注意返回的是可执行文件的位置,不是文件的安装位置,这个位置是根据环境变量查找到的。

nginx的安装位置为:/usr/share/nginx/html这个位置

exit

退出命令行模式

 

docker ps

继续查看正在运行的进程

 

----------------------------------------可选择尝试---------------------------------------------------

// 更改nginx初始化界面

docker cp index.html a42409e14f6a://usr/share/nginx/html

将本地的index.html文件复制到ngixn当中,刷新页面,会发现页面更改了,但是这种更改不能生效,因为在容器内部的更改都是暂时的。要想保持永久性的改变,请使用commit进行提交,后面表示新的images名称。<注意>docker cp命令只能在容器外使用,不能在容器内使用。

 

docker commit -m ‘fun’ 332a6f313a4e nginx-index

提交更改,并创建新的镜像nginx-index

 

docker images

会发现创建了新的镜像nginx-index

-----------------------------------------------------------------------------------------------------

 

docker stop a42409e14f6a

停止运行容器

 

docker ps -a

展示所有运行过的docker容器

 

docker rm 332a6f313a4e

可以删掉容器

 

docker rmi 5e106da96b19

可以删掉镜像


 

 

实例2:创建镜像


docker build 命令用于使用 Dockerfile 创建镜像,上次是通过docker commit创建的镜像,我们还可以通过Dockerfile创建镜像

 

1.创建第一个Dockerfile

 

mkdir d1

cd d1

ls

touch Dockerfile

vi Dockerfile

-----------------------------------------------------------------------------------------------------

FROM alpine:latest

MAINTAINER tys

CMD echo ‘hello docker’

-----------------------------------------------------------------------------------------------------

 

docker build -t hello-docker .

-t是给一个标签,标签名叫做hello-docker  .表示将当前所有的资源交给docker,假如本地没有这个镜像,会从远端下载

 

 

 

 

2.创建第二个Dockerfile

mkdir d2

cd d2

ls

touch Dockerfile

vi Dockerfile

-----------------------------------------------------------------------------------------------------

FROM ubuntu

MAINTAINER circle

RUN apt-get update

RUN apt-get install -y nginx

COPY index.html /var/www/html

ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]

EXPOSE 80

-----------------------------------------------------------------------------------------------------

<注意>COPY的路径不能直接填系统绝对路径,要把想要处理的文件放在Dockerfile的同级目录当中,

如果填 COPY /Users/circleus/index.html /var/www/html,这个时候会返回类似报错:COPY failed: stat /var/lib/docker/tmp/docker-builder877040024/Users/circleus/index.html: no such file or directory

这个也表明了Docker在主机有对应地址,临时地址。

 

 

docker build -t dockerfile2 .

构建新的镜像dockerfile2,构建失败的时候镜像仓库仍然会出现一个镜像,不过名字是<none>,Dockerfile的每一行都产生一个新层。

 

 

实例3:挂载卷volume


1.直接修改宿主机对应内部的卷

docker run -d name nginx -v /usr/share/nginx/html nginx

运行一个nginx容器,通过-v挂载一个卷(juan第四声)

 

docker inspect nginx

然后查看容器元数据,会发现返回信息包含了宿主机地址与容器地址,将宿主机的Source目录挂载到了Destination路径,正常来说这个路径就是宿主机的目录了,但是在Mac上面不一样,Mac中间还有一层,叫虚拟层, 运行的一个Alpine主机,在这个里面运行的docker

 

screen /Users/circleus/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

直接访问是访问不到的,这个时候需要以screen的方式进入Mac的Docker虚拟层,然后输入root登录,好像我这边直接就可以访问了,不需要登录

 

cd  /var/lib/docker/volumes/6476f160ab7e364f3ff5251d69f3aa54733c9b772355729df5134bf908434b86/_data

cd到inspect指示的宿主机目录,然后ls可以看到下面有两个文件,正是docker中nginx的两个文件:50x.html,index.html

 

ls之后,cat index.html

可以看到文件是一致的

 

echo "It's 2019">index.html

往index.html里面添加内容

 

回到宿主机的容器,直接另外打开一个终端

 

docker ps

docker exec -it 1567aca4ce0c /bin/bash

cd /usr/share/nginx/html

cat index.html

进入容器内部查看容器内部的index.html,可以发现index.html的内容变为It’s 2019

 

 

2.本地目录挂载到容器内部:指定目录

docker run -v $PWD/code:/var/www/html nginx

 

cd d2

ls    //返回:Dockerfile index.html

mkdir html

cp index.html html

rm index.html

docke run -d -p 15001:80 -v $PWD/html:/usr/share/nginx/html nginx 

docker ps

docker run最好不要使用本地的80,本地80可能被占用,最后docker ps可以查看到容器启动了。访问localhost:15001可以看到相关信息,要是返回403就说明/usr/share/nginx/html目录没有内容,这个时候使用docker cp将宿主机的文件copy到容器内部,创建index.html。

docker cp index.html  a87d3c7dab1b://usr/share/nginx/html 必须要指定容器id和容器内的目录,中间使用:/来连接,docker cp命令要在容器外使用,这个时候localhost:15001会返回正确的内容。

 

cd ~/d2/html

vi index.html

修改index.html的内容为This is a foolish day!刷新localhost:15001就会返回:This is a foolish day!证明挂载成功,实时生效。

 

3.创建仅有数据的容器,并将这个容器挂载到其他容器里面去

docker run —volumes-from…

 

cd ~

mkdir vol3

cd vol3

mkdir data 

docker create -v $PWD/data:/var/mydata --name data_container ubuntu

这样我们就产生了一个仅有数据的容器

 

docker run -it --volumes-from data_container ubuntu /bin/bash

启动新的容器将数据卷加载到新的容器当中

 

mount

可以发现 /var/mydata已经加载到该容器当中

 

cd /var/mydata

ls

touch whatever.txt

在容器的数据卷中创建whatever.txt

 

exit

pwd

ls

cd data 

ls

会发现宿主机中已经创建了这个文件,ok,说明挂载成功,实际上仅有数据容器可以被多个容器挂载,做到数据共享。

 

 

实例4:Docker的Registry


docker search whalesay

docker pull whalesay

docker push myname/whalesay

 

docker search whalesay

docker pull  docker/whalesay

docker run docker/whalesay cowsay Docker很好玩

docker tag docker/whalesay tangyongshuang/whalesay

docker imasgs

docker login

docker push tangyongshuang/whalesay  // push之前先login

拉取镜像,push自己的镜像

 

 

 

实例5:Docker-compose容器编排,多容器app,搭建Ghost博客


通过编写一个简单的文本文件,文件描述多容器app的文件结构,通过工具将其拉起来。

Mac 和windows是自带这个compose

uname -s

Darwin

uname -m

x86_64

chmod a+x 文件名 所有人都可以执行这个文件

docker-compose —version // compose版本

 

cd ~

mkdir ghost

cd ghost

mkdir ghost

mkdir nginx

mkdir data

ls

cd ghost

touch Dickerfile

vi Dockerfile

-----------------------------------------------------------------------------------------------------

FROM ghost 

COPY ./config.js /var/lib/ghost/config.js

EXPOSE 2368

CMD [“npm”,”start”,”--production”]

-----------------------------------------------------------------------------------------------------

官方已经有一个ghost镜像,我们只需要做一些配置就可以了,这是一个node.js的程序

另外再创建一个config.js文件 

var path = require('path'),
    config;

config = {
    production: {
        url: 'http://mytestblog.com',
        mail: {},
        database: {
            client: 'mysql',
            connection: {
                host: 'db',
                user: 'ghost',
                database: 'ghost',
                port: '3306',
                charset: 'utf-8'
            },
            debug: false
        },
        paths: {
            contentPath: path.join(process.env.GHOST_CONTENT,'/')
        },
        server: {
            host: '0.0.0.0',
            port: '2368'
        }
    }
};
module.exports =config;

cd nginx

touch Dockerfile

vi Dockerfile

-----------------------------------------------------------------------------------------------------

FROM nginx

CORY nginx.conf /etc/nginx/nginx.conf

EXPOSE 15001

-----------------------------------------------------------------------------------------------------

 

touch nginx.conf

vi nginx.conf

-----------------------------------------------------------------------------------------------------

worker_processes 4;

events {worker_connections 1024;}

http {

    server {

        listen 15001;

        location / {

            proxy_pass http://ghost-app:2368;

        }

    }

}

-----------------------------------------------------------------------------------------------------

cd ..

pwd

准备compose文件

touch docker-compose.yml

vi docker-compose.yml

-----------------------------------------------------------------------------------------------------

version: '2'

networks:

  ghost:

services:

  ghost-app:

    build: ghost

    networks:

      - ghost

    depends_on:

      - db

    ports:

      - "2368:2368"

  nginx:

    build: nginx

    networks:

      - ghost

    depends_on:

      - ghost-app

    ports:

      - "15001:15001"

  db:

    images: "mysql:5.7.15"

    networks:

      - ghost

    environment:

      MYSQL_ROOT_PASSWORD: root

      MYSQL_USER: ghost

      MYSQL_PASSWORD: ghost

    volumes:

      - $PWD/data:/var/lib/mysql

    ports:

      - "3306:3306"

-----------------------------------------------------------------------------------------------------

502错误说明nginx.conf配置错误,localhost

 

docker-compose up -d拉起

配置文件修改后

docker-compose stop停止

docker-compose rm

y

docker-compose build

之前使用up -d是因为之前没有镜像,所以会构建镜像,但是这一次不会了必须使用docker-compose build

docker-componse up -d

访问localhost:15001主页面

或者localhost:2368

 

访问后台页面:

localhost:15001/ghost

或者localhost:2368/ghost

 

 

错误总结:

(1)首先,上午的端口没填对,正确的端口应该是2368。nginx.conf与docker-compose都没填对;

(2)其次,/var/lib/mysql的地址没有填对,写成了/var/libmysql;

(3)访问出现localhost 拒绝了我们的连接请求。这个说明我们的端口填错了,实际上是我们nginx配置的代理端口写错了。写成了2386.

(4)访问出现502,我们的服务未启动,原因ghost的Dockerfile是在执行CMD [“npm”,”start”,”--production”]的时候出错,直接注释掉就行。

 

 

 

 

 

 

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐