- Docker FAQ
# 使用nvidia作为基础镜像
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04
# 设置时区环境变量
ENV TZ=Asia/Shanghai
# 设置时区
# 安装 python3/pip/jupyter相关
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& sed -i s@/archive.ubuntu.com/@/mirrors.tuna.tsinghua.edu.cn/@g /etc/apt/sources.list \
&& apt update && apt install python3 pip git -y \
&& apt-get -y install \
pandoc texlive-xetex texlive-fonts-recommended texlive-plain-generic \
latex-cjk-all -y \
&& pip config --user set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \
&& pip install \
jupyterlab jupyterlab-language-pack-zh-CN jupyterlab-git jupyterlab-github \
matplotlib \
numpy \
sympy \
mplfonts
参考:https://yeasy.gitbook.io/docker_practice/install/mirror
ubuntu server20.04
/etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.nju.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"insecure-registries": ["http://192.168.0.105:5000"]
}
参见:https://docs.docker.com/network/proxy/
编辑:~/.docker/config.json
{
"proxies": {
"default": {
"httpProxy": "http://10.1.1.100:8118",
"httpsProxy": "http://10.1.1.100:8118",
"noProxy": "localhost,*.test.example.com,.example2.com"
}
}
}
参见:https://docs.docker.com/config/daemon/systemd/
sudo mkdir /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80"
Environment="HTTPS_PROXY=https://proxy.example.com:443"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
sudo systemctl daemon-reload && sudo systemctl restart docker
docker-compose.yaml:
version: '3'
services:
myservice:
image: myimage
user: ${CURRENT_UID}
working_dir: $HOME
stdin_open: true
volumes:
- /etc/group:/etc/group:ro
- /etc/passwd:/etc/passwd:ro
- /etc/shadow:/etc/shadow:ro
- ./doc:/doc
tty: true
command: tail -f /dev/null
执行:
CURRENT_UID=$(id -u):$(id -g) docker-compose up -d
# tty=true -t
docker run -d -t --rm bash
docker-compose.yaml:
version: '3'
services:
bash:
container_name: bash
image: bash:latest
tty: true
在~/.bashrc加入:
alias dps="docker ps -a --format=\"table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Command}}\t{{.Status}}\t{{.Ports}}\""
效果:
~$ dps
CONTAINER ID NAMES IMAGE COMMAND STATUS PORTS
5232df6e894e gitea-server gitea/gitea:1.13.4 "/usr/bin/entrypoint…" Up 14 minutes 22/tcp, 3000/tcp
7d2d9413bc85 mysql mysql:8.0.23 "docker-entrypoint.s…" Up 14 minutes 3306/tcp, 33060/tcp
...
# 下载一个镜像,可以换成任意一个做测试
$ docker pull curlimages/curl
# 给这个镜像打本地 registry 标签
$ docker tag curlimages/curl:latest 192.168.0.71:5000/curl:0.1.0
# 将打好标签的镜像推送到本地 registry
$ docker push 192.168.0.71:5000/curl:0.1.0
The push refers to repository [192.168.0.71:5000/curl]
72a521189058: Pushed
fb7e65a993e1: Pushed
528912ae6e3c: Pushed
866c03db78bf: Pushed
e983d350de9f: Pushed
71b9a7821e63: Pushed
fafa7d4f4bcf: Pushed
3ac16f3d5560: Pushed
2416cbb93d01: Pushed
90044511e901: Pushed
994393dc58e7: Pushed
0.1.0: digest: sha256:63026076757659e99b03b303522874eb1133594d3db13e0e19b74752b36bf1dd size: 2617
$ DOCKER_REGISTRY=192.168.0.71:5000
# 查看是否上传成功
$ curl -s -X GET $DOCKER_REGISTRY/v2/_catalog | jq .
{
"repositories": [
"app-server",
"curl" # <--有了
]
}
创建目录和index.html
mkdir src
echo 'test site' > src/index.html
docker-compose.yml
version: "3"
services:
web1:
image: nginx
ports:
- 127.0.0.1:80:80
- 192.168.0.81:80:80
volumes:
- ./src:/usr/share/nginx/html
如果不能正常升级或者安装 docker desktop for mac,需要手动删除。
首先,正常删除,比如
brew uninstall --cask docker
或者在应用程序中直接删除 docker 应用。
然后执行 uninstall.sh:
#!/bin/bash
rm -rf ~/Library/Caches/com.docker.docker
rm -rf ~/Library/Group\ Containers/group.com.docker
rm -rf ~/Library/Logs/Docker\ Desktop
rm ~/Library/Preferences/com.docker.docker.plist
rm ~/Library/Preferences/com.electron.docker-frontend.plist
rm -rf ~/Library/Saved\ Application\ State/com.electron.docker-frontend.savedState
rm -rf ~/.docker
sudo rm -rf /usr/local/lib/docker
再重新安装即可。
docker 内置了 tini
以前还有个 dumb-init 做类似的事情。
在容器内以 PID 1 运行的程序负责:
- 清理孤立子进程
- 处理信号
- 返回容器的退出状态
大多数程序不适合在容器内作为 PID 1 运行。例如:
- bash不会将信号传递给其子级;例如,SIGTERM不会导致容器被关闭
- java当发送 SIGTERM 时,即使应用程序完全关闭,也会以退出状态 143 退出
- node不会获取父进程已退出的孤立子进程
Tini提供了一个适合在容器内以 PID 1 运行的程序。
直接使用 docker 命令:
# --init
docker run -d -t --rm --init bash
通过 docker-compose.yaml:
version: "3"
services:
web:
image: alpine:latest
init: true
默认安装的 docker,数据目录在 /var/lib/docker,尤其是 /var/lib/docker/overlay2 因为存放 image 会逐步很大。
需要设置到其他分区上去。
sudo systemctl stop docker
# 复制到其他目录
sudo cp -axT /var/lib/docker /mnt/storage3/docker
# 设置自定义目录
sudo nano /etc/docker/daemon.json
content="
{
"data-root": "/mnt/storage3/docker"
}
"
# 重启
sudo systemctl daemon-reload && sudo systemctl start docker
# 查看是否生效
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bash latest 7ba3c700ba40 12 days ago 13.9MB
docker inspect 7ba3c700ba40| grep WorkDir
"WorkDir": "/mnt/storage3/docker/overlay2/162c2f972554be60547930f603e04a41a184a1a80395abd30c59171fb5e676e9/work"
# 加载
docker load < busybox.tar.gz
docker load --input fedora.tar
# 保存
docker save myimage:latest | gzip > myimage_latest.tar.gz
docker save busybox > busybox.tar
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04
...
EXPOSE 8000
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["python3 openai_api.py --checkpoint-path $CHECKPOINT_PATH --server-name 0.0.0.0"]
docker-compose.yaml:
version: "3"
services:
llm:
image: qwen-llm
container_name: llm
environment:
- CHECKPOINT_PATH=/models/Qwen-14B-Chat-Int4
..