玩一下docker

安装

太久没玩服务端了,心痒痒。上docker本地试试

Dockerfile

编写优雅地Dockerfile

编写优雅的Dockerfile主要需要注意以下几点:

  • Dockerfile文件不宜过长,层级越多最终制作出来的镜像也就越大。
  • 构建出来的镜像不要包含不需要的内容,如日志、安装临时文件等
  • 尽量使用运行时的基础镜像,不需要将构建时的过程也放到运行时的Dockerfile里。

只要记住以上三点就能写出不错的Dockerfile。

FROM node:10.15
MAINTAINER sunhengzhe@foxmail.com
COPY . /app/
WORKDIR /app
RUN npm install pm2 -g
EXPOSE 8003
CMD ["pm2-runtime", "ecosystem.config.js"]
  • FROM 指定基础镜像为 node 的 10.15 版本(node 官方版本可 在此查看
  • MAINTAINER 说明镜像的维护者
  • COPY 命令将宿主机的文件拷贝到镜像中,格式为 COPY [--chown=<user>:<group>] <源路径>... <目标路径>,这里将项目目录下的所有文件都拷贝到镜像中的 /app 目录下。如果目标路径不存在,docker 将自动创建。
  • WORKDIR 用来指定工作目录,即是 CMD 执行所在的目录。
  • RUN 命令用来执行 shell 命令,这里用来安装 pm2
  • EXPOSE 命令用来 声明 运行时容器提供服务端口,但要注意运行时并不会开启这个端口的服务。这个命令主要是帮助使用者理解这个镜像服务的守护端口,以方便配置映射;另外在使用随机端口映射时,会自动随机映射 EXPOSE 的端口
  • CMD 是默认的容器主进程的启动命令。 CMD 能够被 docker run 后面跟的命令行参数替换,有多个 CMD 指令时只有最后一个 CMD 有效

构建镜像

docker build -t express-app:v1 .

运行容器

docker run -p 8003:3000 --name="express-app" -d express-app:v1

docker rundocker createdocker start 两个命令的简写。

  • -d--detach,代表让容器后台运行。
  • -p 指定宿主机和容器的端口映射,左边为宿主机的端口,右边为容器的端口,也就是说访问宿主机的 8003 端口,会映射到容器内的 3000 端口。
  • --name 设置容器别名,如果不指定,docker 会随机生成一个名字,比如 tender_swirles 之类的。

查看运行镜像。docker ps [-a]

添加 -a 参数可以查看所有已启动容器。

进入容器

docker exec -it express-app bash

-i-t 一般结合使用,-i 启动交互模式,-t 指定需要分配终端,可以自行尝试不传其中一个的效果

关闭操作

停止容器

docker stop express-app

删除容器

docker rm express-app

如果删除时容器还在运行,需要加上 -f 参数

删除镜像

docker rmi express-app:v1

常用合集

**docker cp 😗*用于容器与主机之间的数据拷贝。

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。
docker cp /www/runoob 96f7f14e99ab:/www/

将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www。
docker cp /www/runoob 96f7f14e99ab:/www

将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。
docker cp  96f7f14e99ab:/www /tmp/

常用镜像

nginx

FROM nginx
COPY dist/ /usr/share/nginx/html/
COPY nginx/default.conf /etc/nginx/conf.d/default.conf # 覆盖default.conf

docker run --name nginx -p 80:80 \
-v /home/docker-nginx/nginx.conf:/etc/nginx/conf.d/ \
-v /home/docker-nginx/log:/var/log/nginx \
-v /home/docker-nginx/www:/usr/share/nginx/html/ \
-d nginx

version:'3.9'
services:
	testserver:
		image:nginx
    container_name: webserver
    volumes:
      - ./conf.d:/etc/nginx/conf.d/
      - ./www:/usr/share/nginx/html/
      - ./logs/:/var/log/nginx/
	

简单测试:
docker run -p 80:80 --name nginx -d nginx

--name  给你启动的容器起个名字,以后可以使用这个名字启动或者停止容器
-p 映射端口,将docker宿主机的80端口和容器的80端口进行绑定
-v 挂载文件用的
	第一个-v 表示将你本地的nginx.conf覆盖你要起启动的容器的nginx.conf文件
	第二个表示将日志文件进行挂载,就是把nginx服务器的日志写到你docker宿主机的/home/docker-nginx/log/下面
	第三个-v 表示的和第一个-v意思一样的。

no2中挂载方式需要自己准备好nginx.conf 和default.conf文件,我是直接从容器里面复制的,然后根据自己的需要改的

而Nginx的配置文件会包含 default.conf 以及 nginx.conf ;二者的联系为 default.conf 会被 nginx.conf 引入,所以实际上我们只需要配置 default.conf ,然后挂载到 Nginx 容器中即可!

-d 表示启动的是哪个镜像
server {
    listen       80;
    server_name  localhost;
 
    #charset koi8-r;
 
    access_log  /var/log/nginx/host.access.log  main;
    error_log  /var/log/nginx/error.log  error;
    location / {
        root      /usr/share/nginx/html;#vue项目的打包后的dist
        try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
        index  index.html index.htm;
    }
    #对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
    #因此需要rewrite到index.html中,然后交给路由在处理请求资源
    location @router {
        rewrite ^.*$ /index.html last;
    }
    #error_page  404              /404.html;
    
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}


    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

本地copy到云端

Linux 对 Linux 免密登录

1.本地生成秘钥,如果本地有,直接2
ssh-keygen -t rsa
在 ~/.ssh directory
id_rsa : 生成的私钥文件
id_rsa.pub : 生成的公钥文件
know_hosts : 已知的主机公钥清单

2.通过ssh-copy-id的方式写入到服务器
命令: ssh-copy-id -i ~/.ssh/id_rsa.pub <username>@<remote_ip>

cp -r dir1 dir2
即可。
如果dir2目录已存在,则需要使用
cp -r dir1/. dir2
如果这时使用cp -r dir1 dir2,则也会将dir1目录复制到dir2中,明显不符合要求。
ps:dir1、dir2改成对应的目录路径即可。

cp -r /home/www/xxx/statics/. /home/www/statics

source=./dist/ target=/home/docker-nginx/dist/;scp -r $source root@47.95.236.69:$target 
MySQL

拉取镜像。

docker pull mysql

创建容器。

docker run -di --name mysql8 -p 3307:3306 \
-v ~/docker_mysql/conf:/etc/mysql/conf.d \
-v ~/docker_mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 mysql
  • -p:代表端口映射,格式为 宿主机映射端口:容器运行端口。
  • -e:代表添加环境变量 MYSQL_ROOT_PASSWORD 是 root 用户的登陆密码。

连接容器中的 MySQL 时,只需要连接宿主机的 IP + 指定的映射端口即可。

img
连接mysql测试
mysql -h localhost -P 3308 -u root -p

也可以进入容器并使用 MySQL 命令打开客户端

# 进入容器
docker exec -it mysql8 /bin/bash
# 使用 MySQL 命令打开客户端
mysql -uroot -p1234 --default-character-set=utf8

1. 查看MySQL服务状态

sudo mysql.server status

2、重新启动MySQL服务

sudo mysql.server restart

Redis

拉取镜像

docker pull redis

创建容器。

docker run -i -t -p 6379:6379 --name myRedis 
-v /Users/chengchaoyang/mydocker/conf/redis/redis.conf:/etc/redis/redis.conf
-v /Users/chengchaoyang/mydocker/data/redis:/data 
-d redis redis-server /etc/redis/redis.conf 
--appendonly yes
–appendonly yes 开启redis 持久化

连接容器中的 Redis 时,只需要连接宿主机的 IP + 指定的映射端口即可。

img
  1. 修改redis.conf配置文件中的下列项:

创建本地配置文件redis.conf,从官网下载

#注释默认配置中所有的绑定bind,以允许所有的IP都可以访问
#有的博客讲还需要加一条 bind 0.0.0.0  实测不加也可以,只要把原本所有的bind都注释即可
#bind 127.0.0.1
#远程访问
protected-mode no
# 取消注释,设置密码,因为允许任意IP访问,强烈建议配置密码避免redis裸奔
# 否则马上就有一些挖矿病毒进入迅速占据你的虚拟机
requirepass qwer1234
#持久化
appendonly no
#默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
daemonize no
# 修改yes为no,关闭保护模式,允许远程任意IP访问
protected-mode no

远程连接

测试连接:redis-cli -h [localhost] -p IP地址

redis-cli -h 127.0.0.1 -p 6379 

注意这里的-p是你隐射出来的ip

查看docker容器ip地址

docker inspect --format='{{.NetworkSettings.IPAddress}}' ID/NAMES
# 查看 容器ip 地址

MongoDB

拉取镜像。

docker pull mongo

创建容器。

docker run -di --name mongo -p 27017:27017 mongo

连接容器中的 MongoDB 时,只需要连接宿主机的 IP + 指定的映射端口即可

img

Docker Compose

Docker Compose 是 Docker 容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器。

命令

查看容器

docker-compose ps

删除窗口

docker-compose rm laradock_redis_1

拉取镜像

docker-compose pull nginx

重起项目的服务

docker-compose restart

Setup

Run docker-compose build

nginx

nginx:
    image: nginx
    container_name: nginx-start
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - ./dist/:/usr/share/nginx/html/
      - ./logs/:/var/log/nginx/
    ports:
      - 8080:80

redis

redis:
    image: redis
    container_name: redis
    command: redis-server /etc/redis/redis.conf #覆盖容器启动的redis.conf
    volumes:
      - ./redis.conf:/etc/redis/redis.conf
      - ./data:/data
    ports:
      - 6380:6379

难点

VOLUME && -v && mount

一、通过docker run命令

运行命令:docker run --name test -it -v /home/xqh/myimage:/data ubuntu /bin/bash

其中的 -v 标记 在容器中设置了一个挂载点 /data(就是容器中的一个目录),并将主机上的 /home/xqh/myimage 目录中的内容关联到 /data下。

这样在容器中对/data目录下的操作,还是在主机上对/home/xqh/myimage的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。

另一件只有-v参数能够做到而Dockerfile是做不到的事情就是在容器上挂载指定的主机目录例如:

1. $ docker run -v /home/adrian/data:/data debian ls /data
"Mounts": [
        {
            "Name": "0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01",
            主机"Source": "/home/adrian/data",
            镜像"Destination": "/var/lib/docker/volumes/0ab0aaf0d6ef391cb68b72bd8c43216a8f8ae9205f0ae941ef16ebe32dc9fc01/_data", 
            "Driver": "local",
            "Mode": "",
            "RW": true
        }

“Destination” 值是容器的挂载点,"Source"值是对应的主机目录

  1. 运行命令:docker run --name test1 -it -v /data ubuntu /bin/bash

    上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录。通过docker inspect 命令可以查看到。

通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。

还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。

VOLUME ["/data1","/data2"]
"Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data",
"Destination": "/data1",
 
"Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data",
"Destination": "/data2",

容器共享卷(挂载点)

在 docker run中使用 --volumes-from标

docker run \
-p 3000:80 \
-d --name vuenginxnew \
--mount type=bind,source=$HOME/SelfWork/docker/vueclidemo/nginx,target=/etc/nginx/conf.d \
--mount type=bind,source=$HOME/SelfWork/docker/vueclidemo/dist,target=/usr/share/nginx/html \
nginx

纠错

安装过程中,如果发现容器启动失败,使用docker logs查看容器日志

本例中docker容器名为redis,查看日志命令为:docker logs -f -t --tail 100 redis

docker inspect [containerid]/[name]

docker inspect db                                                ✔  163807:36:14
[
    {
        "Id": "636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0",
        "Created": "2021-04-27T12:35:11.5392669Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "--character-set-server=utf8mb4",
            "--collation-server=utf8mb4_unicode_ci",
            "--default-authentication-plugin=mysql_native_password"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 16597,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-04-27T23:37:32.9769096Z",
            "FinishedAt": "2021-04-27T23:37:23.5432795Z"
        },
        "Image": "sha256:0627ec6901db4b2aed6ca7ab35e43e19838ba079fffe8fe1be66b6feaad694de",
        "ResolvConfPath": "/var/lib/docker/containers/636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0/hostname",
        "HostsPath": "/var/lib/docker/containers/636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0/hosts",
        "LogPath": "/var/lib/docker/containers/636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0/636641cabcd1ee16092c1464b028679dbe9aff496bed9dfc240e1bed2dde42a0-json.log",
        "Name": "/db",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/Users/cwz/kkk/mysql/data:/var/lib/mysql:rw",
                "/Users/cwz/kkk/mysql/my.cnf:/etc/my.cnf:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "kkk_app-network",
            "PortBindings": {
                "3306/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "33061"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": [],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/6541b939a2c0ad3e9953bfe898edaf693764e2cde56d62ad36309d4fa25b17f1-init/diff:/var/lib/docker/overlay2/88bfd7c828014de3670d17a5ddaebe79c44ca14070a1c9e3f7a80a5cb58a3c79/diff:/var/lib/docker/overlay2/0ae5c16bb1f9df67091739900a3cfc4f09ba92b66eca862d2cc5fcbbfabc3146/diff:/var/lib/docker/overlay2/371f950b0cf38d53d9536c592a5c7d98289f38ab6ee9588801d70fd2d085d91c/diff:/var/lib/docker/overlay2/d37a862de9fc54f4840b78a31b0ea0e034d927e65b92f899c618f7fa944ff137/diff:/var/lib/docker/overlay2/b3e14412827965c50315c846afd34cd3a40e20801dbe2a7d427c3f3f995fb119/diff:/var/lib/docker/overlay2/a82739b5a1f2336d4f2a216b3f4a4f9ab55319ddcf8e72881112637ffecfb021/diff:/var/lib/docker/overlay2/3b57ff4c5068a67defb34afced98445d242307ccf0b64a6470be764f5863e745/diff:/var/lib/docker/overlay2/3daca23272ad0875c3ee39f06675959f3abab9b925efa342663fd51d8e3b30b5/diff:/var/lib/docker/overlay2/3474137cd32190ce06e45903d23aa7c777ab201474d364e09f49b7b931f0a7b2/diff:/var/lib/docker/overlay2/a89a925c53f43d2575d4328eaa4d26176a9a765260747bc195cd35d3934c795d/diff:/var/lib/docker/overlay2/b7ef041594eee10722a49f6fc209540c84b62ba453621ac95ca6b72ed3b89e87/diff:/var/lib/docker/overlay2/928afa9318fa8d78912ead936c9961e5318162c097f970cb744ed4eb7dd0fe82/diff",
                "MergedDir": "/var/lib/docker/overlay2/6541b939a2c0ad3e9953bfe898edaf693764e2cde56d62ad36309d4fa25b17f1/merged",
                "UpperDir": "/var/lib/docker/overlay2/6541b939a2c0ad3e9953bfe898edaf693764e2cde56d62ad36309d4fa25b17f1/diff",
                "WorkDir": "/var/lib/docker/overlay2/6541b939a2c0ad3e9953bfe898edaf693764e2cde56d62ad36309d4fa25b17f1/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/cwz/kkk/mysql/data",
                "Destination": "/var/lib/mysql",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/cwz/kkk/mysql/my.cnf",
                "Destination": "/etc/my.cnf",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "636641cabcd1",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "ccc=333",
                "MYSQL_USER=test",
                "MYSQL_PASSWORD=123456",
                "MYSQL_ROOT_PASSWORD=123456",
                "MYSQL_DATABASE=fendou",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.24-1debian10"
            ],
            "Cmd": [
                "--character-set-server=utf8mb4",
                "--collation-server=utf8mb4_unicode_ci",
                "--default-authentication-plugin=mysql_native_password"
            ],
            "Image": "mysql",
            "Volumes": {
                "/etc/my.cnf": {},
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "aad574eb3639cb0a5bad29f1da465ec3c007f907d80bd6e6e61ed4f97a718885",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "kkk",
                "com.docker.compose.project.config_files": "docker-compose.yml",
                "com.docker.compose.project.working_dir": "/Users/cwz/kkk",
                "com.docker.compose.service": "db",
                "com.docker.compose.version": "1.28.5"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "d27be75574f4aad55ad31c491e9a12a762684e89f1bbcdaa240d0308fcb074ec",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "3306/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "33061"
                    }
                ],
                "33060/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/d27be75574f4",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "kkk_app-network": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "636641cabcd1",
                        "db"
                    ],
                    "NetworkID": "ea6bb64819f85349364e2256276296b6c05340ac1b03922fb86aeb0c95f382fa",
                    "EndpointID": "64ad84042834cfe99926ed02ca46c8fe4d69bc5034ade917d6477d78b4ca8b15",
                    "Gateway": "192.168.144.1",
                    "IPAddress": "192.168.144.2",
                    "IPPrefixLen": 20,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a8:90:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

最终配置

version: '3.7'
services:
  db:
    image: mysql
    container_name: db
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/my.cnf
      # - ./mysql/init:/docker-entrypoint-initdb.d/
    env_file: .env
    restart: always
    environment:
      # - MYSQL_HOST=127.0.0.1
      - MYSQL_USER=test #创建test用户
      - MYSQL_PASSWORD=123456 #设置test用户的密码
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=fendou
    command:
      --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
      --default-authentication-plugin=mysql_native_password
      #  --init-file /data/application/init.sql
    ports:
      - '33061:3306'
    networks:
      - kkkproject
  node3:
    build: .
    image: node
    container_name: node3
    restart: always #重启规则
    volumes:
      - .:/usr/node/app/
    environment:
      - DB_HOST=db
    ports:
      - 4000:3000
    depends_on: 
      - db
    networks:
      - kkkproject
    command: npm run dev

networks:
  app-network:
    name: kkkproject
    # driver: bridge
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 每天花5分钟阅读和学习Docker PDF,可以帮助我们快速掌握Docker的基本知识和使用技巧。首先,我们可以利用这5分钟来了解Docker的概念和基本原理,如容器化技术、镜像和容器的关系等。同时,也可以学习Docker的核心功能,如映像构建、容器管理、网络配置等。通过阅读Docker PDF,我们可以了解Docker的各种命令和选项的使用方法,例如docker run、docker build等。另外,我们可以学习如何使用Docker Compose来编排和管理多个容器的应用程序,以及如何使用Docker Swarm来进行容器集群的部署和管理。此外,阅读Docker PDF还可以让我们了解到一些Docker的最佳实践和常见问题,以及如何解决这些问题。通过每天花5分钟来Docker PDF,我们可以不断积累对Docker的理解和掌握,提高我们的工作效率和技术水平。 ### 回答2: 每天花费5分钟Docker PDF,对于对Docker有基本了解的人来说是一个很好的学习和提升技能的方式。 首先,我们可以阅读一些Docker的入门资料和教程。可以搜索并下载一些与Docker相关的PDF文档,例如《Docker入门指南》等。通过阅读这些资料,我们可以了解Docker的基本概念、使用方法以及与之相关的命令。 其次,我们可以学习Docker的一些常用命令和操作。可以找到一些包含Docker命令和操作示例的PDF文档,例如《Docker常用命令手册》等。通过学习这些命令和操作,我们可以更好地理解和掌握Docker的使用技巧,能够更高效地管理和使用容器。 此外,我们还可以学习Docker的一些高级特性和技术。有一些PDF文档专门介绍和讲解Docker的高级特性和技术,例如Docker的网络配置、数据卷的使用、镜像构建等等。通过学习这些高级特性和技术,我们可以更好地应用Docker解决实际问题,并优化我们的容器化应用。 最后,我们可以进行一些实践和实验。可以找到一些包含Docker实践和实验的PDF文档,例如一些Docker的实战项目或者案例分析。通过实践和实验,我们可以将理论知识应用到实际问题中,也可以发现和解决在实践中遇到的困难和挑战。 总结来说,每天花费5分钟阅读和学习Docker的相关PDF文档,可以帮助我们提升Docker的基础知识和技能,掌握Docker的常用命令和操作,了解Docker的高级特性和技术,并通过实践和实验运用所学知识。这样,我们可以更好地应用和管理Docker容器,为我们的工作和项目开发带来更多的便捷和效率。 ### 回答3: 每天花5分钟学习和应用Docker将是非常值得的。Docker是一种容器化技术,可以将应用程序和其所有依赖项打包在一个独立的容器中,从而实现快速部署和管理。通过学习Docker,你可以更方便地构建、发布和运行应用程序,同时提高开发效率和部署灵活性。 在5分钟的时间里,你可以阅读并理解有关Docker的一些核心概念和基本命令的PDF文档。这些内容包括容器、镜像、容器注册表、Dockerfile等。了解这些概念将帮助你更好地理解和使用Docker。 此外,你还可以学习如何在本地环境中安装Docker,并通过一些简单的命令启动容器和运行应用程序。你可以尝试使用Docker创建一个简单的Web应用,如一个Hello World页面,并通过浏览器访问它。这将帮助你快速上手并体验Docker的优势。 为了更深入地学习Docker,你可以查看更多高级的Docker功能,如网络设置、数据卷和多容器应用的部署。学习这些功能可以帮助你更好地管理和扩展应用程序。 每天花5分钟学习和应用Docker的PDF指南是非常实用的,并且你可以通过不断积累知识和实践来提高自己的技能。无论你是开发人员、测试人员还是系统管理员,掌握Docker技术都将为你的工作带来很多便利和效益。开始行动吧,每天花5分钟Docker,让你的工作更加高效和充满乐趣!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值