docker 中使用 ubuntu 镜像(最简官方原生)时,可以部署个最简单的 ubuntu 容器
都直到 ubuntu 换成国内的源会快很多,但是 docker 的原生 ubuntu 镜像运行的容器连 vi 都没有,需要换源只能手动进行了。需注意的是,源的版本需要和 ubuntu 版本一致,这里版本指的不是版本号,而是 codename 代码版本,可以通过 lsb_release -a 来查看

codename 里显示的就是代码版本了。在换的源中间可以指定代码版本,例如我的就是 focal。docker 原生的 ubuntu 连 lsb_release 都没有,可以使用 apt install lsb-release 来安装,或直接换 focal 的源。
rm /etc/apt/sources.list # 删除默认的源文件
# 也可以重命名源文件,以做备份
# mv /etc/apt/sources.list /etc/apt/sources.list.bak
# 添加 163 的镜像源
echo "deb http://mirrors.163.com/ubuntu/ focal main restricted universe multiverse" >/etc/apt/sources.list
echo "deb http://mirrors.163.com/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/ubuntu/ focal main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
# 添加阿里云的镜像
echo "deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse" >/etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
# 添加清华源
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse" >/etc/apt/sources.list
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
# 添加中科大源
echo "deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse" >/etc/apt/sources.list
echo "deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
echo "deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse" >>/etc/apt/sources.list
有些源,例如中科大和清华的,需要使用证书,docker 原生 ubuntu 没有安装,所以需要安装一下。
apt install ca-certificates
ubuntu 容器建立好后,能够直接进入 root 用户,如果需要密码,可以使用 passwd root 命令重新设置。
容器内的服务如果需要自动启动,可以使用 systemctl enable 服务名 来启动。如果没有 systemctl 则需要先安装。(需要注意的是,容器必须运行在特权模式下,即 --privileged=true,可以使用 docker inspect 容器名 来查看。如果没有运行在特权模式,可以配置 config.v2.json(路径可以看后面)文件同目录下的 hostconfig.json 文件,修改"Privileged":false =>"Privileged":true )
apt install systemd
在使用 systemctl 的时候,查看 system status 状态,如果报错:System has not been booted with systemd as init system (PID 1). Can't operate. ,则需要进行配置。退出容器,关闭 docker 服务,并在宿主机进行配置
docker inspect 容器名
# 查看并记住 id 项,使用 vim 或其他方法编辑 config.v2.json 文件
vim /var/lib/docker/containers/[刚才查看的 id]/config.v2.json
将 "Path":"bash"(或 "Path": "/bin/bash")改为:"Path":"/sbin/init" ,将 "Cmd":["bash"](或 "Cmd":["/bin/bash"]) 改为: "Cmd":["/sbin/init"] 。
然后重新运行 docker 、运行容器。有时这一部也会报错:
Error response from daemon: failed to create shim: OCI runtime create failed: runc create failed: unable to start container process: exec: "/sbin/init": stat /sbin/init: no such file or directory: unknown
说明没有 /sbin/init 文件,那就重新安装一个
apt install init
然后运行容器,在容器内部执行 systemctl enable 服务名 ,执行 systemctl status 查看状态。会发现容器内部的服务设置成了自动启动了。
使用镜像创建能够自启动的容器,则需要在生成容器时添加初始化参数,例如 ubuntu 的初始化程序在 /sbin/init ,则
docker run -dit --name 容器名称 -p 端口号:端口号 --privileged=true 镜像名称 /sbin/init
如果 apt update 时报错:
The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY xxxxxxxxxxxxxx
意思是公钥不可用,重新获取并注册证书即可
# 获取公钥证书
gpg --keyserver keyserver.ubuntu.com --recv-keys xxxxxxxxxxxxxxxx
# 注册公钥证书
gpg --export --armor xxxxxxxxxxxxxxxx | sudo apt-key add -
ubuntu 在 update 后会更新缓存列表,此列表也会占用大量的空间资源,打包镜像之前可以删除以节省空间。
rm -rf /var/lib/apt/lists/*
需注意的是,如果在删除缓存前将容器提交为镜像,那么实际数据信息就进入了镜像的 history。以此镜像生成容器然后删除缓存再提交镜像,会发现大小没有变化。
在基础容器中安装 mysql,可以参考普通 linux 系统安装 mysql,使用包管理器安装就可以了。也可以直接下载镜像。
宿主机创建数据目录和配置文件:
mkdir -p /mydata/mysql/conf
mkdir -p /mydata/mysql/data
创建配置文件和输入内容:
echo "[mysqld]" >> /mydata/mysql/conf/my.cnf
echo "port=3306" >> /mydata/mysql/conf/my.cnf
echo "bind-address=0.0.0.0" >> /mydata/mysql/conf/my.cnf
echo "character-set-server=utf8" >> /mydata/mysql/conf/my.cnf
echo "default_authentication_plugin=caching_sha2_password" >> /mydata/mysql/conf/my.cnf
echo "max_allowed_packet=20971520" >> /mydata/mysql/conf/my.cnf
echo "expire_logs_days=7" >> /mydata/mysql/conf/my.cnf
echo "server_id=1" >> /mydata/mysql/conf/my.cnf
echo "[client]" >> /mydata/mysql/conf/my.cnf
echo "default-character-set=utf8" >> /mydata/mysql/conf/my.cnf
echo "[mysql]" >> /mydata/mysql/conf/my.cnf
echo "default-character-set=utf8" >> /mydata/mysql/conf/my.cnf
使用默认镜像创建容器:
docker run -dit --name mysql -p 3306:3306 -v /mydata/mysql/conf/my.cnf:/etc/mysql/conf.d/mysql.cnf -v /mydata/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --restart=always --network common-network mysql
需注意的是,安装 mysql 时创建的容器需要添加 –privileged=true 参数,否则会报错 Cannot stat file /proc/31/fd/29: Permission denied 没有权限。
docker run -dit --privileged=true --name=mysql -p 3306:3306 ubuntu
mysql 需要修改配置文件和用户访问权限,以支持远程访问。
mysql 配置文件为:/etc/mysql/mysql.conf.d/mysqld.cnf。可以从容器内部复制到宿主机本地修改,然后在复制进容器
# 在宿主机
docker cp 容器:/etc/mysql/mysql.conf.d/mysqld.cnf 本地路径
docker cp 本地路径/mysqld.cnf 容器:/etc/mysql/mysql.conf.d/
修改用户访问权限:
# 查看各用户访问权限
select host,user from user;
# 设置 root 用户所有主机均可以使用其进行访问
update user set host = '%' where user = 'root';
# 刷新授权
FLUSH PRIVILEGES;
mysql 安装好后,在提交镜像前也需要删除缓存:
rm -rf /var/lib/apt/lists/*
rm -rf /var/lib/mysql/*
redis 的 docker 镜像版本还可以,使用也挺简单,可以使用。需要注意的是,采用默认映像启动会报警告:
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
需要在服务器(不是容器内)执行 sysctl vm.overcommit_memory=1 或者执行一下语句:
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf \
&& sysctl -p
在基础容器中安装 redis,可以参考普通 linux 系统安装 redis,使用包管理器安装。
首先创建配置文件
mkdir -p /mydata/redis/conf
touch /mydata/redis/redis.conf
然后写入一些需要的配置信息
echo "appendonly yes" >> /mydata/redis/redis.conf # 持久化
echo "port 6379" >> /mydata/redis/redis.conf # 端口
echo "bind 0.0.0.0" >> /mydata/redis/redis.conf # 访问主机
echo "dbfilename dump.rdb" >> /mydata/redis/redis.conf # 数据库文件
echo "dir /data" >> /mydata/redis/redis.conf # 工作目录
echo "# requirepass 123456" >> /mydata/redis/redis.conf # 数据库密码
echo "save 900 1" >> /mydata/redis/redis.conf # 保存策略
echo "save 300 10" >> /mydata/redis/redis.conf # 保存策略
echo "save 60 10000" >> /mydata/redis/redis.conf # 保存策略
echo "maxmemory 1GB" >> /mydata/redis/redis.conf # 占用最大内存
然后使用此配置文件创建容器
docker run -p 6379:6379 --name redis -v /mydata/redis:/data --restart=always --network common-network -dit redis redis-server /data/redis.conf
重新梳理一下各参数的作用:
docker 官方 python 应该是基于 debian 的 bullseye 版本的,所以换源使用
rm /etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ bullseye main non-free contrib" >/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ bullseye-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ bullseye-backports main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ bullseye main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ bullseye-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ bullseye-backports main non-free contrib" >>/etc/apt/sources.list
可以使用官方 python 镜像来创建容器。创建容器的时候,最好指定映射目录(存放源码用),指定工作目录和指定运行的脚本文件(或指令)。例如(使用 django 举例):
docker run -dit --name python -p 8000:8000 -p 222:22 -v /mydata/python/src:/src -w /src/project --restart=always --network common-network python python manage.py runserver
除了开启服务端口的映射外,还映射了 22 端口,以方便 ssh 登录进行代码修改、调试等操作。
需注意的是,docker 发现前台没有运行程序会自动关闭释放资源,所以如果创建一个简单的python容器,例如只运行 hello world ,则会输出字符直接关闭。这个特性使得直接创建 python 容器运行 django 程序,会报没有依赖库(django 等库都没有安装),然后直接关闭容器。处理这种问题,则需要先建立一个运行 shell 的 python 容器(可以映射到程序文件夹,以便获取 requirements.txt),然后安装依赖库,再手动执行 python manage.py。如果需要使用到重启自动运行的功能,则需要将其打包为镜像,然后再以添加执行参数的方式创建容器。
根据 requirements.txt 来安装依赖库
pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
为了方便远程调试代码,可以开启 ssh 服务,如果没有,可以重新安装
apt install openssh-server
然后需要配置一下 ssh 的设置文件 /etc/ssh/sshd_config,允许远程登录:
完成后,查看一下是否开启了
ps -ef | grep ssh
dpkg -l | grep ssh
如果没有开启,则需要手动运行一下
/etc/init.d/ssh start
另外记得创建 root 的密码
passwd root