Docker常用操作

Share
Docker常用操作
Photo by Ian Taylor / Unsplash

安装

Windows安装Docker到F盘(非系统盘)

Start-Process -FilePath 'Docker_Desktop_Installer.exe' -Wait -ArgumentList "install --installation-dir=F:\DockerDesktop"

改变容器、镜像文件位置

以管理员权限启动Docker Desktop,Settings-Resources-Disk iamge location

配置dockerhub国内源

阿里云:容器镜像服务 (aliyun.com)

其他源

more /etc/docker/daemon.json

输入以下文件:

{
    "registry-mirrors": [
        "https://kk8u6omk.mirror.aliyuncs.com",
        "https://docker.1ms.run",
        "https://proxy.1panel.lilve",
        "https://docker.xuanyuan.me",
        "https://docker.m.daocloud.io",
        "https://docker.rainbond.cc",
        "https://docker.1panel.live"
    ]
}

添加当前用户到docker组

sudo groupadd docker  # 如果不存在则创建
sudo usermod -aG docker $USER  # $USER 是当前用户名
newgrp docker  # 立即生效(仅当前会话)

Dockerfile

# 使用官方 Python 精简镜像作为基础
FROM python:3.11-slim-bookworm

# 构建参数
ARG uid
ARG gid

# 换清华源
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources && \
    apt-get update && \
    apt-get install -y --no-install-recommends \
        vim-common \
        libgfortran5 \
        libgomp1 \
        locales \
        libssl3 && \
    rm -rf /var/lib/apt/lists/* && \
    localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8

RUN pip install --no-cache-dir -r requirements.txt \
    toml \
    -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple



# 创建用户和目录结构
RUN groupadd -g $gid user && \
    useradd -m -g user -u $uid user && \
    mkdir -p /opt/tsysmart/platform/data/log && \
    chown user:user /opt/tsysmart -R

WORKDIR /opt/tsysmart

# 添加平台文件
ADD --chown=user:user ./minplf.tgz /opt/tsysmart/platform

# 切换到非root用户
USER user


# 环境变量设置
ENV TZ="Asia/Shanghai" \
    LANG="zh_CN.utf8" \
    PATH="/opt/tsysmart/platform/bin:$PATH" \
    LD_LIBRARY_PATH="/opt/tsysmart/platform/lib:$LD_LIBRARY_PATH" \
    TH_ENV_FILE="/opt/tsysmart/platform/config/th_env.ini"

# 数据卷声明
VOLUME ["/opt/tsysmart/platform/data", "/opt/tsysmart/platform/user"]
  • apt:添加--no-install-recommends:减少不必要的依赖安装
  • pip:添加--no-cache-dir:pip安装时不缓存包
  • ADD:添加压缩包并解压,库文件删掉.a文件(静态库)

ADD vs COPY

特性ADDCOPY
支持解压✅(自动解压 .tar, .tar.gz, .tar.xz 等)❌(仅复制文件,不解压)
支持远程 URL✅(可下载并解压远程文件)❌(仅限本地文件)
推荐用途需要解压或下载文件时普通文件复制

最佳实践

  • 优先使用COPY(除非需要 ADD 的解压或下载功能)。
  • 如果只是复制文件(不解压),用 COPY 更清晰:
    COPY archive.tar.xz /target/ # 不会解压,直接复制 .tar.xz 文件
  • 如果需要 自动解压,用 ADD
    ADD archive.tar.xz /target/ # 自动解压到 /target/

注意事项

  1. ADD不会解压嵌套的压缩包
    如果 .tar.xz 内部还有 .tar.gz,只会解压第一层。
  2. ADD下载远程文件时不会解压
    dockerfile

    ADD https://example.com/archive.tar.xz /target/ # 下载但不解压
  3. tar.xz需要 Docker 支持 xz 工具
    如果基础镜像没有 xz 工具(如 Alpine Linux 默认不安装),ADD 仍然可以解压,因为 Docker 引擎本身处理解压。

验证 ADD 是否解压成功

可以在 Dockerfile 里加 RUN ls 检查:

dockerfile

FROM alpine ADD example.tar.xz /test/ RUN ls -l /test/ # 查看是否解压

总结

  • ADD支持.tar.xz,会自动解压(和 .tar.gz 类似)。
  • 如果只是复制文件(不解压),优先用 COPY
  • 远程 URL 的 .tar.xz 不会自动解压,需手动处理。

镜像

查看

docker images

# 查看每层大小
docker history <image_name> --format "table {{.Size}}\t{{.CreatedBy}}"

导出

docker save -o <导出文件名>.tar <镜像名>:<标签>
# 或
docker save <镜像名>:<标签> > <导出文件名>.tar

导入

docker load -i <导出文件名>.tar
# 或
docker load < <导出文件名>.tar

压缩导出导入

docker save my-image:tag | gzip > my-image.tag.tar.gz
gunzip -c my-image.tag.tar.gz | docker load

docker save my-image:tag | xz > my-image.tag.tar.xz
docker save my-image:tag | pigz > my-image.tag.tar.gz

构建

docker build -f <Dockerfile.name> -t <image_name>:<tag_name> .

别忘了最后面的点,是构建路径

最好保证当前目录只有必须文件,构建时会将工作目录所有文件发给docker守护进程。

容器

创建(run)

--it # i交互、t伪终端

--rm  # 容器退出时就能够自动清理容器内部的文件系统

映射

docker run -v /宿主机/路径:/容器内/路径 镜像名称

# 例如,如果你的文件在容器内的/app/config.json,可以:
docker run -v $(pwd)/config.json:/app/config.json 你的镜像

root进入

docker run -it -u root --entrypoint bash <container_name>

查看(ps)

# 显示所有运行中的容器
docker ps

# 显示所有的容器,包括未运行的。
docker ps -a

启停(start/stop/restart)

# 停用全部容器
docker stop $(docker ps -q)

删除(rm)

# 删除全部容器
docker rm $(docker ps -aq)

# 一条命令实现停用并删除容器:
docker stop $(docker ps -q) & docker rm $(docker ps -aq)

进入(exec)

docker exec -it 容器id /bin/bash

# 启动失败进入
docker run -it --entrypoint /bin/bash your_image_name

# 退出
Ctrl + D

Compose

构建

docker-compose build

启动

docker-compose up -d

重启

docker-compose up -d --force-recreate --no-deps <service-name>

停止

#停止所有服务
docker-compose down

清理

完整对比

命令停止的容器未使用的镜像未使用的卷未使用的网络
docker system prune✅ 删除❌ 仅 <none> 镜像❌ 不删除✅ 删除
docker system prune -a✅ 删除✅ 所有未使用的镜像❌ 不删除✅ 删除
docker system prune -a --volumes✅ 删除✅ 所有未使用的镜像✅ 删除✅ 删除

请谨慎使用这些命令,特别是在生产环境中。

# 一次性清理所有未使用的资源(包括停止的容器、未使用的网络、悬挂的镜像等)
docker system prune  
# 加上 -a 可以清理未使用的镜像(包括未被任何容器引用的镜像)
docker system prune -a 
# 删除 Docker 系统中几乎所有未使用的资源
docker system prune -a --volumes

这个更强大的命令会:

1. 删除所有未使用的容器prune 默认行为)

  • 停止的容器会被删除(类似 docker container prune)。
  • 运行中的容器不受影响

2. 删除所有未被引用的镜像-a 的作用)

  • 默认 docker system prune 只会删除 悬挂镜像<none>:<none>,即未被任何容器或镜像引用的中间层镜像)。
  • -a选项会额外删除所有未被容器使用的镜像,包括那些有名字但未被任何容器引用的镜像(如 ubuntu:latest 如果没有容器使用它,也会被删除)。

3. 删除所有未使用的卷--volumes 的作用)

  • 默认 docker system prune不会删除卷(即使它们未被使用)。
  • --volumes会删除所有未被容器或服务引用的卷(类似 docker volume prune)。
  • ⚠️ 危险:如果卷中有重要数据(如数据库文件),会被永久删除!

4. 删除未使用的网络prune 默认行为)

  • 未使用的自定义网络会被删除(类似 docker network prune)。
  • 默认的 bridgehostnone 网络不会被删除。

日志

-f 或 --follow 参数会实时跟踪日志输出

-t 参数会在每行日志前添加时间戳

-tail=100先显示最近的100行日志,然后开始跟踪新日志

docker logs --tail=100 -ft rtdb-server

Read more

【避坑指南】从 TinyDB 文件损坏,聊聊文件截断与磁盘刷盘的底层原理

【避坑指南】从 TinyDB 文件损坏,聊聊文件截断与磁盘刷盘的底层原理

在 Python 轻量级开发中,TinyDB 因其“零部署、文件即数据库、支持对象化查询”的特性,成为了存储配置信息、多租户元数据的神器。 但在高频写入或异常崩溃的场景下,你是否遇到过这样的诡异现象:导出的 JSON 文件末尾莫名其妙多出了几个 NULNUL(\x00)空字节,导致整个数据库报 JSON 无法解析的错误? 本文将带你还原这个经典的“文件空洞”Bug,并分享如何通过自定义存储类 MyJSONStorage 彻底解决它。 一、 现象还原:消失的尾巴与诡异的 NUL 在默认情况下,TinyDB 的 JSONStorage 是这样写入文件的: 1. seek(0) 指针回到文件开头。 2. write(json_data) 写入序列化后的 JSON 字符串。 3. truncate(

By 樊泽豪
搭建K3s集群

搭建K3s集群

K8s环境部署 简介 搭建 K3s + Rancher + Longhorn + MetalLB环境 K3s K3s是一款轻量级Kubernetes发行版,其核心优势在于: * 极致轻量:单个二进制文件不到100MB,仅需512MB内存即可运行,启动和资源消耗远低于标准集群。 * 功能齐全:通过CNCF认证,100%兼容标准Kubernetes API,并内置了常用组件,开箱即用。 * 灵活的数据存储:可以使用外部数据库(mariadb)替代etcd,降低初始资源。 Rancher Rancher是一个开源容器管理平台,核心能力包括: * 统一纳管:可集中管理任意K8s集群(包括K3s/RKE2、云厂商托管集群及已有集群)。 * 降低门槛:提供直观图形界面及开箱即用的CI/CD、监控、服务网格等工具链。 * 安全合规:支持AD/LDAP对接及精细化RBAC,实现跨集群统一安全策略。 Longhorn Longhorn 是一款专为 Kubernetes 设计的轻量级、可靠且易用的分布式块存储系统,它通过容器和微服务将现有存储资源转化为持久卷,

By 樊泽豪
如何在 Ghost 博客中添加类似 Word 的左侧固定目录(纯干货)

如何在 Ghost 博客中添加类似 Word 的左侧固定目录(纯干货)

当我们在 Ghost 博客中撰写长文时,一个类似 Word 导航窗格的目录能极大提升读者的阅读体验。本文将分享如何通过 Code Injection(代码注入) 快速实现一个完全静止、不随点击乱跳、长标题自动换行的优雅左侧悬浮目录。 实现效果 * 完全固定: 目录稳居文章左侧,只有正文跟随鼠标滚动。 * 绝对静止: 修复了常见插件点击目录项时,目录自身会产生二次跳动的痛点。 * 清晰完整: 长标题自动换行显示,绝不裁剪文字。 * 移动端友好: 在手机或平板等小屏幕上自动隐藏,防止遮挡正文。 部署步骤 无需修改任何主题源文件,只需登录 Ghost 后台,进入 Settings -> Code Injection(代码注入),将以下两段代码全选覆盖粘贴即可。 1. 注入到 【Site Header】 在 Site Header 框中复制并完全粘贴以下代码(包含 Tocbot 官方样式与自定义微调

By 樊泽豪
Git Worktree 完全指南:告别分支切换焦虑

Git Worktree 完全指南:告别分支切换焦虑

在多个分支间频繁切换,每次都要重新加载环境、重启服务?git worktree 让你同时拥有多个工作目录,互不干扰,效率翻倍。 为什么需要 Worktree? 日常开发中,我们经常面临这样的场景: * 正在 feature 分支开发新功能,突然要紧急修复 hotfix 分支的 Bug * 想同时对比两个分支的代码差异,或者并行跑两个版本的服务 * 每次切换分支,IDE 都要重新索引,编译缓存失效,等待时间漫长 常规的 git checkout 或 git switch 虽然能切换分支,但同一时间只能在一个分支上工作。如果你切走再切回来,之前的环境(如依赖安装、编译产物)可能已经丢失或需要重建。 git worktree 的解决方案:在同一个 Git 仓库中,创建多个独立的工作目录,每个目录对应不同的分支,它们共享同一个 .git 对象库(

By 樊泽豪