Docker使用过程中问题汇总
下面是我在使用docker过程中遇到的一些问题以及解答,现记录下来备查。
1. 为什么有很多<none>:</none>镜像,有的删除不掉,有些却删除不掉?¶
我们执行命令docker images -a有时候会发现不少docker rmi image_name删除这些none镜像时候,有时候能够成功,有时候却不能成功。这究竟为什么?
我们知道镜像是分层的,上面一层依赖下一层,下一层是上一次的父镜像层。就像下面这样:
我们可以通过docker inspect查看镜像ID 和父层镜像ID
上图中镜像ip-scout的ID是28ee11309524,它的父镜像层ID是a8e836f776fa, 接着我们看看上图父镜像层信息:
我们发现ip-scout镜像的父镜像层就是docker build或docker pull过程中产生的中间层镜像,这些none镜像是无法删除的。最上层镜像由于我们命名了所以不再是你none,就好比28ee11309524的名称就是ip-scout:latest
我们可以通过docker history查看所有层:
untagged和dangling,这类镜像占用空间,可以使用下面命令进行删除的:
如何删除已退出的容器的镜像?¶
我们可以使用下面命令
docker stop $(docker ps -a | grep "Exited" | awk '{print $1 }')
docker rm $(docker ps -a | grep "Exited" | awk '{print $1 }')
如何查看容器完整ID?¶
我们使用docker ps命令查看到的容器ID是短ID,我们可以使用以下命令查看完整ID:
如何查看容器运行的命令?¶
有时候我们忘记当时是怎么运行容器的,可以通过以下命令查看:
docker stack不支持加载.env文件,怎么解决?¶
docker compose支持.env文件来设置环境变量,但是docker swarm集群部署模式下不支持.env环境,有时候我们确实很需要,可以这样:
生成环境怎么使用docker部署nodejs应用?¶
生产推荐使用pm2部署nodejs应用,支持自动重启,集群部署。
下面是构建nodejs应用镜像Dockerfile
FROM node
WORKDIR /app
COPY . /app
RUN npm install pm2 -g
RUN npm install --only=production
EXPOSE 8989
CMD ["pm2-runtime", "/app/server.js", "--name", "your-app-name"]
后续步骤略
docker swarm模式下使用traefik做负载均衡时候无法获取到客户端IP?¶
问题原因是docker swarm模式本身问题moby/moby#25526。
通过配置traefik服务对外暴露端口可以解决此问题:
traefik:
image: traefik
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
docker swarm模式下一个容器有多个端口,使用traefik做复制该如何配置?¶
我们可以配置traefik的段标签(segment labels)来解决此问题,格式如下:
traefik.<segment_name>.backend=BACKEND
traefik.<segment_name>.port=PORT
traefik.<segment_name>.domain=DOMAIN
traefik.<segment_name>.frontend.auth.basic=EXPR
更多查看traefik On containers with Multiple Ports (segment labels)
当我们构建nodejs应用镜像,全局安装某依赖时候,有时候出现权限拒绝该怎么解决?¶
我们一般使用官方镜像作为父镜像构建我们应用的镜像,有时候在运行npm install xxx -g命令时候会提示类似如下的权限问题:
这是由于镜像默认用户是root,我们全局安装某些依赖时候,限制使用root安装。这时候可以更改镜像用户和依赖安装目录:
USER node
RUN mkdir /home/node/.npm-global && mkdir /home/node/app
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin
docker部署mysql时候,日志目录不可写问题?¶
使用docker-compose进行编排:
# docker-compose.yml
version: '3.3'
services:
mysql-master:
image: mysql:5.7
container_name: mysql-master
restart: always
ports:
- "3306:3306"
environment:
- "MYSQL_ROOT_PASSWORD=123456"
volumes:
- /opt/mysql-master-slave/data/master:/var/lib/mysql # data目录
- /opt/mysql-master-slave/log/master:/var/log/mysql # 日志目录
- /opt/mysql-master-slave/mysqld-master.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf # 配置
容器启动时候,提示日志目录写入失败:
docker部署grafana数据目录权限导致问题¶
部署grafana时候由于挂载的数据目录权限问题会导致:
GF_PATHS_DATA='/var/lib/grafana' is not writable.
You may have issues with file permissions, more information here: http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later
mkdir: cannot create directory '/var/lib/grafana/plugins': Permission denied
docker-composer.yml文件:
grafana:
image: grafana/grafana
ports:
- "127.0.0.1:3100:3000"
environment:
- "GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana"
- GF_SECURITY_ADMIN_PASSWORD=123456
volumes:
- $PWD/data/grafana:/var/lib/grafana
解决办法:更改挂载目录的用户和组
docker容器内外相互拷贝数据¶
从宿主机上拷贝文件或目录到容器内:
从容器内拷贝文件或目录到宿主机上:



