Docker使用教程
Docker使用安装及常见命令
1.Windows安装docker desktop 注意事项:
在Windows上Docker显示“Docker Engine stopped”的问题可能有多种原因
-
检查WSL2配置
确认WSL2已正确安装并设置为默认版本,使用命令wsl --set-default-version 22。
-
检查Hyper-V设置
确保Hyper-V功能已启用,这是Docker在Windows上运行的前提3。 -
检查虚拟化支持
在BIOS中确认虚拟化技术(如Intel VT-x或AMD-V)已开启2。
2.常见命令
docker pull #拉取镜像
docker build -t myapp:latest . #当前目录下的dockerfile文件构建镜像。
docker build –f path/Dockerfile -t myapp:latest #指定目录下的dockerfile文件构建镜像
docker run --name < 容器名称 /ID> < 镜像名称> #运行一个容器,如果不指定名称,系统会自动生成一个容器名称
docker exec -it < 容器名称 /ID> #进入容器执行交互式命令
docker save -o my_image.tar <镜像名称;标签> #另存打包镜像
docker load -i open-webui.tar #指定文件加载镜像
docker rename <容器名称/ID> #重命名容器
docker compose -f docker/docker-compose-base.yml up -d #通过Docker Compose 启动依赖的服务
docker compose -p ragflow up -d #-p 给容器一个组名
docker export < 容器名称 /ID> <保存的文件名称>.tar #导出容器
docker system df #查看docker磁盘使用情况,加-v可以查看详细使用情况。
docker cp 源地址 目标地址 #从宿主机拷贝文件到容器
docker volume create 卷名字 #创建数据卷
docker volume ls #查看所有数据卷
docker volume inspect 卷名字 #查看某个数据卷详情
docker volume prune 卷名字 #清除数据卷
docker update container_name --restart=always #让容器跟着docker重启。或者在docker run的时候就把--restart=always 加进去。
docker image inspect myexpose:1.0 #查看 镜像暴漏端口:
docker image prune -a #删除所有未使用的镜像,包括没有被任何容器引用的镜像
docker builder prune #清理Docker的构建缓存
docker volume prune和docker network prune分别删除未使用的卷和网络
docker system prune 命令可以删除所有未被使用的镜像层、容器、卷和网络,从而释放磁盘空间
docker compose down --rmi all #删除刚配置的镜像
-it 以交互模式运行容器 /bin/bash 启动bash shell分配终端
-i 源头文件
-o 输出文件s
-t 指定标签tag
-f 指定文件路径或者是强制命令
-d后台运行
-p 映射端口号
- docker通常不需要导出容器,但可能需要导出容器的配置:
docker inspect container_name >/path/to/backup/confainer_name_config.ison
- docker挂载本地数据卷文件夹:通常用-v或者--volumn或者--mount,常用命令形式为:
- docker run -v 宿主机路径:/容器/目录 镜像名称
- docker run --mount type=bind,source=/home/username/data,target=/app/data my_image #将宿主机的
/home/username/data
目录挂载到容器的/app/data
目录
docker挂载常用做法:1.运行一个不加 -v 参数的容器:docker run -d --name ng1 -p 6060:80 nginx:1.25.4
2.相关配置拷贝到宿主机: docker cp ng1:/etc/nginx/nginx.conf /data/nginx/conf/
.
3.移除原有容器(此时挂载的文件里的内容不会移除),跑一个新的加-v 的容器 docker run -d --name ng2 -v /data/nginx/conf/nginx.conf /etc/nginx -p6061:80 nginx:1.25.4
- docker迁移:通常迁移镜像\数据卷\容器的json配置:
- 导出:
docker save -o my image.tar <镜像名称:标签> #另存打包镜像
docker cp container_name:/path/in/container/ local/backup/path
docker inspect container_name >/path/to/backup/container_name config.json - 导入:
docker load -i open-webui.tar #指定文件加载镜像
cp -r /back/up/my _data /var/lib/my _data #把数据拷贝到相应路径,要与原来的路径一致
cat /backup/my_configjson #查看容器配置
- 导出:
3.互联网镜像导入离线电脑上操作方法:
- docker save Image_name > local_image.tar
- 将 local_image.tar导入离线电脑
- 离线电脑如果是Windows直接进入所在文件夹load就可以了
如果是Linux系统,Linux系统安装lrzsz软件包:在Debian/Ubuntu系统中apt install lrzsz
在 CentOS/RHEL系统中 yum install lrzsz
安装完成后(上传文件到服务器《本地-远程》),终端中进入要保存到目录 cd /path/
,输入rz命令回车,选择要接受的文件。开始接收。
接收完成后,ls
查看文件列表,而后进行加载操作 docker load < local_image.tar
,这样就载入镜像了,然后启动容器:docker run -d -p [宿主端口:服务端口] --name my_container local_image
. docker ps查看正在运行的容器。
4.Dockerfile 制作镜像
通过Dockerfile文件
内容组成一般由几部分组成:
#第一部分基础镜像
FROM alpine
#第二部分:维护者信息,现在不用maintainer了改用LABLE
MAINTAINER mainatiner="chh"\
name="damo"\
abc="asd"
ENV xx="wo" #定义环境变量,非必要,可以不要
#第三部分,镜像操作指令
RUN echo dokerfiletest
#第四部分 CMD命令,就是容器启动执行的脚本
CMD sleep 10;echo success
5.Docker Compose
** 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 YAML 文件配置应用的服务、网络和卷等资源** (一个服务需要多个容器进行组合式就用到了这个,容器之间的连接需要用到这个,docker run link也可以实习但比较麻烦。)
Windows do安装dockers以后会自动安装do cker-compose,但Linux不会,需要运行一个命令curl -L http://..........> /usr/loacl/bin/docker-compose 安装,然后还要赋予这个工具脚本文件权限:sudo chmod +x /usr/loacl/bin/docker-compose
下载
通过YML文件配置应用程序需要的所有服务。
将本地Python项目导出为Docker镜像
6.docker项目启动端口冲突
例如有一个项目已经占用80和443了,新的项目也要用,怎么办??**
Docker 项目端口冲突的解决办法主要有以下几种,可以根据你的场景选择最合适的:
🛠 核心思路:避免多个容器同时绑定到主机的同一个端口
-
修改新项目的端口映射 (最简单常用)
-
这是最常见的做法。启动新项目的容器时,使用
-p
参数将容器内部的端口映射到主机上不同的、未被占用的端口。 -
命令示例:
# 假设新项目内部使用 80 端口,将其映射到主机的 8080 端口 docker run -d -p 8080:80 --name new-project-container new-project-image # 假设新项目内部使用 443 端口,将其映射到主机的 8443 端口 docker run -d -p 8443:443 --name new-project-container new-project-image
-
访问方式: 通过
http://主机IP:8080
或https://主机IP:8443
访问新项目。 -
优点: 简单直接,不需要改动现有项目。
-
缺点: 访问 URL 需要带端口号,不够优雅(尤其对最终用户)。
-
-
使用反向代理 (推荐,更灵活、接近生产环境)
-
在主机上运行一个反向代理服务器(如 Nginx, Traefik, Caddy, HAProxy)。
-
将所有外部进入主机 80 和 443 端口的流量都引导到这个反向代理。
-
反向代理根据请求的域名 (Host Header) 或 路径前缀 (Path Prefix) 将流量转发到内部运行的不同容器(这些容器可以映射到主机上任意空闲的高端口)。
-
配置示例 (Nginx):
# 配置在 nginx.conf 或 sites-available/ 下的某个文件 server { listen 80; server_name project-new.example.com; # 新项目的域名 location / { proxy_pass http://localhost:8080; # 指向映射了新项目容器 80 端口的主机端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; server_name project-old.example.com; # 老项目的域名 location / { proxy_pass http://localhost:80; # 指向映射了老项目容器 80 端口的主机端口 (通常是默认) ... # 同样设置必要的 headers } } # 443 (HTTPS) 配置类似,需要额外配置 SSL 证书
-
容器启动:
# 老项目 (假设已经占用了主机的 80/443) docker run -d -p 80:80 -p 443:443 --name old-project-container old-project-image # 新项目 (映射到主机的高端口) docker run -d -p 8080:80 --name new-project-container new-project-image # HTTP docker run -d -p 8443:443 --name new-project-container new-project-image # HTTPS (如果容器内需要)
-
访问方式:
- 老项目:
http://project-old.example.com
/https://project-old.example.com
- 新项目:
http://project-new.example.com
/https://project-new.example.com
(通过反向代理自动转发到8080
/8443
)
- 老项目:
-
优点:
- 所有服务都通过标准的 80/443 端口访问,URL 更简洁专业。
- 可以在代理层统一管理 SSL/TLS 证书终止,简化容器配置。
- 方便添加负载均衡、缓存、访问控制等高级功能。
- 容器只需绑定内部端口,主机端口映射灵活。
-
缺点: 需要额外设置和配置反向代理服务器。
-
-
停止或迁移占用端口的老项目
-
如果老项目是临时的、测试的,或者可以暂时停止,那么最简单的方法是先停掉占用 80/443 的老项目容器。
-
停止容器:
docker stop old-project-container
-
然后就可以启动需要使用 80/443 端口的新项目容器了。
-
如果老项目很重要但可以迁移,考虑将其修改为映射到其他主机端口(使用第一种方法),然后再启动新项目到 80/443。
-
优点: 简单。
-
缺点: 需要中断或改动现有服务,通常不可行。
-
-
修改新项目的容器内部监听端口 (如果应用支持)
- 有些应用程序允许通过环境变量或配置文件修改其内部监听的端口。
- 例如,一个 Node.js 应用可能通过
process.env.PORT
设置端口,一个 Nginx 容器可以通过修改配置文件中的listen
指令。 - 修改后,将这个新端口(比如
8080
)映射到主机端口(比如8080
或任意空闲端口)。 - 优点: 避免了容器内部端口的冲突(虽然主机端口冲突是另一回事,但通常内部端口冲突更少见)。
- 缺点: 需要修改应用或服务的配置,并非所有应用都支持灵活修改监听端口。主机端口冲突仍需通过映射或代理解决。
-
使用
host
网络模式 (通常不推荐)-
启动容器时使用
--network host
参数,容器将直接使用宿主机的网络栈,不再进行端口映射。容器内监听 80 端口的服务就直接在主机 80 端口上暴露。 -
命令示例:
docker run -d --network host --name new-project-container new-project-image
-
问题:
- 这并不能解决冲突! 如果新项目容器内部也监听 80/443 端口,而老项目(无论是否容器)已经占用了主机 80/443,新容器启动时依然会失败,因为它试图绑定已经被占用的端口。
- 容器失去了网络隔离性,安全性降低。
- 容器端口无法再映射到其他主机端口。
-
适用场景: 极少数需要极致网络性能或特殊网络配置的场景。对于解决端口冲突,这个选项基本无效且不推荐。
-
-
使用 Docker Compose 协调端口 (本质是方法1的编排)
-
如果你用 Docker Compose 管理项目,在
docker-compose.yml
文件中清晰地定义每个服务的端口映射,确保主机端口不冲突。 -
示例:
version: '3' services: old-project: image: old-project-image ports: - "80:80" # 老项目占用主机80 - "443:443" # 老项目占用主机443 new-project: image: new-project-image ports: - "8080:80" # 新项目映射主机8080到容器80 - "8443:443" # 新项目映射主机8443到容器443
-
这本质上还是方法1(修改端口映射),但用 Compose 文件管理更清晰。
-
-
使用服务发现和内部网络 (在 Swarm/K8s 中更常见)
- 在 Docker Swarm 或 Kubernetes 集群中,通常不直接绑定主机端口。服务通过内部 overlay 网络通信,并通过 Ingress Controller (类似反向代理) 将外部流量引入集群。Ingress Controller 本身会占用主机的 80/443 端口,然后根据规则转发到集群内不同的服务(这些服务在集群内部使用自己的端口)。这是大规模部署的标准模式,解决端口冲突是其核心功能之一。
📌 总结与建议
- 最快速简单 (临时/开发): 方法1 - 修改新项目的端口映射。 启动新容器时用
-p 新主机端口:容器内部端口
。访问时带上新端口号。 - 最优雅灵活 (生产/长期/多项目): 方法2 - 使用反向代理 (Nginx/Traefik等)。 这是强烈推荐的解决方案。它让你所有项目都能通过标准的 80/443 端口访问,通过域名区分服务,管理方便,扩展性强。
- 如果老项目可停可改: 方法3 - 停止/迁移老项目。
- 如果新项目配置灵活: 方法4 - 修改新项目的内部监听端口 (配合方法1或2使用)。
🧪 操作注意事项
- 查看端口占用: 在尝试启动前,用
netstat -tulpn | grep :80
和netstat -tulpn | grep :443
(Linux/macOS) 或Get-Process -Id (Get-NetTCPConnection -LocalPort 80).OwningProcess
(PowerShell on Windows) 确认端口确实被哪个进程(Docker容器)占用。 - 修改配置后重启: 无论是修改 Docker 命令/Compose 文件,还是修改反向代理配置或应用内部配置,通常都需要重启容器或服务使更改生效。
- 备份配置: 修改反向代理或应用配置前做好备份。
- 分步测试: 修改后,逐步测试每个服务是否按预期工作。
对于你的情况(已有项目占用了 80/443,新项目也要用),方法2(反向代理)通常是长期和最佳的解决方案。 方法1是最快的临时解决方案。选择哪种取决于你的具体需求和环境复杂度。😊