赞
踩
第一步: 拉项目镜像
docker pull 镜像名
第二步: 基于镜像生成 docker(红色背景是项目的端口映射, 数据卷挂载, 定制化自启动和 root
登录权限), 这里按照自己的项目需求来:
docker run -dit -p 222:22 -p 8081:8080 -p 80:80 -p 3307:3306 -p 6380:6379 -p 15673:15672 -p 22123:22122 -p 23001:23000 -v /d/usr:/home -v /c/Windows/identification:/data/identification --privileged --restart=always -h 用户名 --name=容器名 镜像名: 版本号 /bin/bash /etc/rc.d/enable
第三步: 进入 docker, 添加或修改 docker(这里看需求修改: 我个人添加表 sql, 备份文件, 脚本文件迁移到 docker 上)用到了以下指令:
1、进入 docker
docker start 容器名
docker exec -it 容器名 bash
2、宿主机复制文件到 docker(当然也可以用 Xftp):
docker cp 文件路径 容器长 ID:docker 容器中的路径
3、连接数据库执行 sql 文件
①连接 MySQL: mysql -u 用户 -p 密码
②选择数据库: use 数据库名
;
③执行 sql 文件: source 脚本文件全路径 (/data/xxx.sql)
第四步: docker commit
命令生成副本镜像
sudo docker commit -m "备注" -a "修改人" 容器 id 镜像名: 新版本号
第五步: 验证副本镜像(重复第二步骤、第三步骤, 查看自己的修改)
第六步: docker push
命令上传至 Docker Hub 上
sudo docker push 镜像名: 新版本号
第七步: 登录 Docker Hub 查看自己的提交
第一步: 基于容器导出 tar 包(这里 LZ 的 tar 包名: luntek-ic-platform3d5.tar
), export
命令 (-o
: 指向导出 tar 文件, 也可以用 “>” 大于号替代)
# container 表示容器 id 或容器名
docker export [options] container
# 如果没有启动的容器, 则需要启动容器
docker run -dit luntek/ic-platform:3.5
# 使用 export 导出容器, 使用的是容器 id
docker export > luntek-ic-platform3d5.tar 容器 ID
# 或者
docker export -o luntek-ic-platform3d5.tar 容器 ID
第二步: docker import 将 tar 包解压导入为镜像(这里 LZ 的镜像名: luntek/ic-platform:3.5)
docker import [options] file|URL|- [REPOSITORY[:TAG]]
docker import luntek-ic-platform3d5.tar luntek/ic-platform:3.5
# 或者
cat luntek-ic-platform3d5.tar | docker import - luntek/ic-platform:3.5
第三步: docker 上传至 docker hub
sudo docker push luntek/ic-platform:3.5
第一步: 基于镜像(可多个镜像)中导出文件(这里 LZ 的文件名: luntek-ic-platform3d5
, 镜像名: luntek/ic-platform:3.5
), save
命令 (-o
: 指向导出文件, 也可以用 “>” 大于号替代)
# images [images...] 可以有多个 images 镜像
docker save [options] images [images...]
docker save -o /root/luntek-ic-platform3d5 luntek/ic-platform:3.5
# 或者
docker save > /root/luntek-ic-platform3d5 luntek/ic-platform:3.5
第二步: 基于文件解压导入镜像(这里 LZ 的绝对路径文件名: /root/luntek-ic-platform3d5
), docker load
命令 (-i
: 指向解压导入文件, 也可以用 “<” 小于号替代)
docker load -i /root/luntek-ic-platform3d5
# 或者
docker load < /root/luntek-ic-platform3d5
第三步: docker 上传至 docker hub
sudo docker push luntek/ic-platform:3.5
docker save $(docker images -q) -o /path/to/save/mydockersimages.tar
docker load -i /path/to/save/mydockersimages.tar
To create an image from a container, you can use the docker commit command:
$ docker commit <container> <image>
Where:
container
is the name or the ID of the container that can be obtained using the docker ps
command.image
is the name of the image you want to create.For example:
$ docker commit 4b2386a65651 node-server:beta
Note that if the container you are creating an image from is running, Docker will automatically pause it while the image is committed, in order to reduce the likelihood of encountering data corruption during this process.
Overwriting Dockerfile Instructions
A Dockerfile is a text file that contains all the necessary instructions for building a Docker image. These instructions can be used for installing and configuring command line tools, declaring environment variables, exposing ports, copying files from the local environment, and so on.
When creating an image from a container, these instructions can be overwritten using the -c
flag (short for change).
For example, to change an environment variable:
$ docker commit -c
"ENV NODE_ENV=development" <container> <image>
Note it is possible to change multiple instructions at once:
$ docker commit -c 'WORKDIR /app' -c
'CMD ["node", "app.js"]' <container> <image>
Following could be useful:
docker tag 4b2386a65651 hello_world_node
docker commit --author amit.sharma@sentinelone.com nginx_base authored
docker commit --message 'this is a basic nginx image' nginx_base mmm
docker commit --pause=false nginx_base wo_pause
More: docker commit docs
$ docker --help | grep -E "(export|import|load|save)"
export Export a container's filesystem as a tar archive
import Import the contents from a tarball to create a filesystem image
load Load an image from a tar archive or STDIN
save Save one or more images to a tar archive (streamed to STDOUT by default)
docker save
will indeed produce a tarball, but with all parent layers, and all tags + versions.docker export
does also produce a tarball, but without any layer/history.It is often used when one wants to “flatten” an image, as illustrated in “Flatten a Docker container or image” from Thomas Uhrig:
docker export <CONTAINER ID> | docker import - some-image-name:latest
However, once those tarballs are produced, load/import are there to:
docker import
creates one image from one tarball which is not even an image (just a filesystem you want to import as an image)Create an empty filesystem image and import the contents of the tarball
By itself, this imported image will not be able to be run from docker run
, since it has no metadata associated with it (e.g. what the CMD
to run is.)
docker load
creates potentially multiple images from a tarred repository (since docker save
can save multiple images in a tarball).Loads a tarred repository from a file or the standard input stream
By using load
you can import the image(s) in the same way they were originally created with the metadata from the Dockerfile, so you can directly run them with docker run
.
To summarize what we’ve learned, we now know the following:
save
works with Docker images. It saves everything needed to build a container from scratch. Use this command if you want to share an image with others.
load
works with Docker images. Use this command if you want to run an image exported with save. Unlike pull, which requires connecting to a Docker registry, load can import from anywhere (e.g. a file system, URLs).
export
works with Docker containers, and it exports a snapshot of the container’s file system. Use this command if you want to share or back up the result of building an image.
import
works with the file system of an exported container, and it imports it as a Docker image. Use this command if you have an exported file system you want to explore or use as a layer for a new image.
RUN apt-get --no-install-recommends install -y libaio-dev \
&& rm -rf /var/lib/apt/lists/*
创建镜像
前提: 当前文件有一个 Dockerfile
, 用于指示创建镜像的流程。本博客有很多 Dockerfile
的案例代码供查询。
创建镜像命令: docker build -t charlywan/hexo_blog:latest .
查看镜像
docker images
删除镜像
docker rmi 67a7f3c78c5c
# 2. 或者
docker rmi 67a
上面的 rmi
是 remove image 的简写。
docker 镜像 mac 下保存路径
mac 下 docker 的镜像保存位置:
/Users/{YourUserName}/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2
在 Dockerfile 中安装 deb 软件包时, 某些软件将 tzdata 作为依赖项安装。
tzdata 会以交互方式提醒用户选择使用位置。
Configuring tzdata
------------------
Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.
1. Africa 4. Australia 7. Atlantic 10. Pacific 13. Etc
2. America 5. Arctic 8. Europe 11. SystemV
3. Antarctica 6. Asia 9. Indian 12. US
Geographic area:
可能一直会卡在这个界面(我就遇到了)。
为了解决这个问题, 我们需要将 tzdata 设置为非交互方式。
首选的方法是在 Dockerfile 的第一条 RUN 之前加入以下配置:
ENV DEBIAN_FRONTEND=noninteractive
第二个方法是, 在 DEBIAN_FRONTEND=noninteractive 条件下使用命令 apt install 或 apt-get install 配置安装 tzdata:
RUN DEBIAN_FRONTEND=noninteractive apt install -y tzdata
这将自动选择默认配置安装 tzdata。
安装常用软件
Alphine 默认不带 Bash 的, 所以要另外安装:
RUN apk --update add --no-cache git openssh bash && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /var/cache/apk/*
配置 SSH
RUN sed -i "s/UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config && sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config && sed -i "s/PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config
遇到的问题
sshd: no hostkeys available -- exiting
# 3. 生成 host key, 只针对 alpine, 其它的默认就有
RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa -b 4096 &&\
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa &&\
ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa &&\
ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t ed25519
RUN chmod 600 /etc/ssh/ssh_host_rsa_key &&\
chmod 600 /etc/ssh/ssh_host_dsa_key &&\
chmod 600 /etc/ssh/ssh_host_ecdsa_key &&\
chmod 600 /etc/ssh/ssh_host_ed25519_key
Docker 的官方并没有提供 hexo 镜像, 所以我们需要自己做。我们根据网友制作的 Dockerfile 我们知道可以基于 Node 的官方镜像制作。
制作可以基于 Debian 和 alphine, 这两者的 Dockfile 我都写好了。
其中为了以后 hexo 的开发我还加了 bash, git, ssh 等常规服务。
Alphine 版
FROM node:10.1.0-alpine
MAINTAINER CharlyWan "xxx@xxx.com"
# 4. prepare work directory
WORKDIR /blog
# 5. 修改 root 密码, 便于远程登录
RUN echo root:xxx | chpasswd
# 6. install ssh
# 7. RUN apt-get update
# 8. RUN apk add --no-cach openssh-server
RUN apk --update add --no-cache git openssh bash && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /var/cache/apk/*
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh/
# 9. 生成 ssh key
# 10. RUN ssh-keygen -q -t rsa -b 2048 -f /root/.ssh/id_rsa -P '' -N 'xxx'
# 11. 复制与移动 key
# 12. RUN mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
# 13. RUN chmod 600 /root/.ssh/authorized_keys
COPY ["authorized_keys", "/root/.ssh/authorized_keys"]
COPY ["oschina", "/root/.ssh/id_rsa"]
RUN chmod 600 /root/.ssh/authorized_keys &&\
chmod 600 /root/.ssh/id_rsa
# 14. 生成 host key, 只针对 alpine, 其它的默认就有
RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa -b 4096 &&\
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa &&\
ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa &&\
ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t ed25519
RUN chmod 600 /etc/ssh/ssh_host_rsa_key &&\
chmod 600 /etc/ssh/ssh_host_dsa_key &&\
chmod 600 /etc/ssh/ssh_host_ecdsa_key &&\
chmod 600 /etc/ssh/ssh_host_ed25519_key
# 15. git config
RUN git config --global user.name "chuanwan" &&\
git config --global user.email "xxx@xxx.com" &&\
git config --global gui.encoding utf-8
# 16. 禁止密码登录等 SSH 设置
RUN sed -i "s/UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config && sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config && sed -i "s/PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config
# 17. install hexo
RUN npm install hexo-cli -g
# 18. replace this with your application's default port
EXPOSE 4000
EXPOSE 22
# 19. 以下注释掉, 多条 CMD 只有最后一条 CMD 有效
# 20. run ssh deamon
CMD ["/usr/sbin/sshd", "-D"]
# 21. run hexo server
# 22. CMD ["hexo", "server","-i","0.0.0.0"]
# 23. COPY ["run.sh", "/root/run.sh"]
# 24. RUN chmod +x /root/run.sh
# 25. ENTRYPOINT ["/root/run.sh"]
# 26. ENTRYPOINT ["/bin/bash"]
Debian 版
做是做了, 但是建议还是用 alphine 吧, 因为大牛好像都倾向使用它。
FROM node:latest
MAINTAINER CharlyWan "xxx@xxx.com"
# 27. prepare work directory
WORKDIR /blog
# 28. 修改 root 密码, 便于远程登录
RUN echo root:xxx | chpasswd
# 29. install ssh
RUN apt-get update &&\
apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd &&\
mkdir -p /root/.ssh/
# 30. 生成 ssh key
# 31. RUN ssh-keygen -q -t rsa -b 2048 -f /root/.ssh/id_rsa -P '' -N 'xxx'
# 32. 复制与移动 key
# 33. RUN mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
# 34. RUN chmod 600 /root/.ssh/authorized_keys
COPY ["authorized_keys", "/root/.ssh/authorized_keys"]
COPY ["oschina", "/root/.ssh/id_rsa"]
RUN chmod 600 /root/.ssh/authorized_keys &&\
chmod 600 /root/.ssh/id_rsa
# 35. git config
RUN git config --global user.name "chuanwan" &&\
git config --global user.email "xxx@xxx.com" &&\
git config --global gui.encoding utf-8
# 36. 禁止密码登录
RUN sed -i "s/.*PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config
# 37. install hexo
RUN npm install hexo-cli -g
# 38. replace this with your application's default port
EXPOSE 4000
EXPOSE 22
# 39. 以下注释掉, 多条 CMD 只有最后一条 CMD 有效
# 40. run ssh deamon
# 41. CMD ["/usr/sbin/sshd", "-D"]
# 42. run hexo server
# 43. CMD ["hexo", "server","-i","0.0.0.0"]
COPY ["run.sh", "/root/run.sh"]
RUN chmod +x /root/run.sh
ENTRYPOINT ["/root/run.sh"]
run.sh
:
# 44. !/bin/bash
# 45. start ssh deamon
/usr/sbin/sshd -D
# 46. /usr/sbin/sshd -D & 不能使用 &, 因为如果到后台去运行了, 整个 container 就退出了
# 47. start hexo server
# 48. hexo server -i 0.0.0.0
启动 hexo 容器
docker-compose.yml
version: '2'
services:
hexo:
image: charlywan/hexo_blog:latest
container_name: hexo
ports:
- "4000:4000/tcp"
- "2222:22/tcp"
volumes:
- /data/hexo_blog/hexo_blog_src:/blog
创建 Nginx 镜像
由于 Docker 的官方 Nginx 镜像并未暴露 443 端口, 而我的网页需要 https 的支持, 所以创建新的 Nginx 镜像很有必要。
基于 Docker 的特性, 我们只需要在其官方镜像的基础上稍加些东西暴露 443 端口即可, 我们尽量选择 Alpine 的镜像, 占用空间真的小。
Dockerfile
:
FROM nginx:1.13.12-alpine
LABEL maintainer="charlywan <1@qq.com>"
EXPOSE 443
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]
修改 Nginx 的默认配置文件
因为我们是在 Docker 的官方 Nginx 镜像基础上做的, 所以无需在镜像里面提取, 直接到 https://hub.docker.com/_/nginx/ 里面的 Github 中去找并修改。
根据官方的 Dockerfile 我们只需要 2 个文件: /etc/nginx/nginx.conf
和 /etc/nginx/conf.d/default.conf
。(依据是什么? 因为这两个文件有 COPY
操作。)
/etc/nginx/nginx.conf
:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server_tokens off; # 关闭显示 Nginx 版本号提升安全性
gzip on; # 启用压缩节约带宽
include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/default.conf
:
server {
listen 443 ssl http2;
server_name xxx.net www.xxx.net blog.xxx.net;
ssl on;
ssl_certificate /etc/letsencrypt/live/xxx.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.net/privkey.pem;
#rewrite /.git/COMMIT_EDITMSG http://xxx.net permanent;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
# Protect ~ files
location ~ ~$
{
access_log off;
log_not_found off;
deny all;
return 404;
}
# Protect .git files
location ~ /\.git
{
access_log off;
log_not_found off;
deny all;
return 404;
}
# Don't expose hidden files to the web
location ~ /\. {
return 404;
}
location ~ /.git/ {
deny all;
return 404;
}
#rewrite ^/(.*)\.(git|asp|aspx|asa|asax|dll|jsp|cgi|fcgi|sh|bash)(.*)$ http://xxx.net permanent;
#rewrite ^/(.git) http://xxx.net permanent;
location / {
# 当发现 URL 里面含有 .git 时, 返回 "error"
if ($request_uri ~* ".git") {
return 200 "error";
}
root /usr/share/nginx/html;
index index.html index.htm;
}
# 缓冲保留时间
location ~ .*\.(?:js|css)$
{
expires 7d;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
server {
listen 80;
server_name xxx.net www.xxx.net blog.xxx.net;
rewrite ^(.*) https://$server_name$1 permanent;
}
让 Nginx 使用 HTTPS 连接
从上面的配置文件我们可以看到, 我们是强制了使用 HTTPS 的。Nginx 中使用 HTTPS 非常简单, 只需要在 /etc/nginx/conf.d/default.conf
里面加入三行即可:
ssl on;
ssl_certificate <PATH TO A fullchain.pem FILE>;
ssl_certificate_key <PATH TO A privkey.pem>;
启动 Nginx 容器
docker-compose.yml
:
version: '2'
services:
hexo:
image: nginx:1.13.12-alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- /data/hexo_blog/public:/usr/share/nginx/html
- /home/ubuntu/nginx/container/nginx.conf:/etc/nginx/nginx.conf
- /home/ubuntu/nginx/container/default.conf:/etc/nginx/conf.d/default.conf
- /home/ubuntu/certbot/etc/letsencrypt:/etc/letsencrypt
$ sudo docker-compose up -d
Registry 是 Dcoker 官方的一个私有仓库镜像, 可以用来存储和管理自己的镜像
Harbor 是 VMWare 公司提供的一个用于存储和分发 Docker 镜像的企业级 Registry 服务器, 通过添加一些企业必需的功能特性, 例如安全、标识和管理等, 扩展了开源 Docker Distribution。支持多租户、 可扩展的 API 和 Web UI、支持跨多个注册表(包括 Harbor) 进行复制、支持身份集成和基于角色的访问控制。
Harbor 是 Docker Registry 的更高级封装, 提供分层传输机制, 优化网络传输; 提供 WEB 界面, 优化用户体验; 支持水平扩展集群; 有良好的安全机制; 提供了基于角色的访问控制机制等等, 比 Registry 强大太多了, 推荐使用 Harbor。
构建 Docker 仓库方式除了使用 Registry 之外, 还可以使用 Harbor, 如下为 Registry 方式缺点:
Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器, 通过添加一些企业必需的功能特性, 例如安全、标识和管理等, 扩展了开源 Docker Distribution。
作为一个企业级私有 Registry 服务器, Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制, 镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控。另外, Harbor 也提供了高级的安全特性, 诸如用户管理, 访问控制和活动审计等。
Harbor 仓库部署两种方式, 一种是 off-line , 一种是 on-line, 即离线和在线安装, 此处选择离线安装:
curl -L https://github.com/docker/compose/releases/download/1.8.0/run.sh > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
[root@www ~]# wget -c https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.0.tgz
harbor.cfg
, 修改 hostname
为本机 IP 地址, 下所示:[root@www harbor]# vim harbor.cfg
hostname = 192.168.179.100
安装 Habor, 命令如下: ./install.sh
登陆 Habor WEB 平台, 默认用户名: admin
, 默认密码: Harbor12345
, 可以在 habor.cnf
自己设置密码
# 49. 下面可以看到安装完 docker hub 的机器上面跑着很多容器, 所以不建议部署了 docker hub 的机器上跑别的应用, 只跑 docker hub 来为我们提供镜像
[root@www harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4db9f3a2c228 goharbor/nginx-photon:v1.7.0 "nginx -g 'daemon of?? 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp nginx
fbb0fb69d986 goharbor/harbor-jobservice:v1.7.0 "/harbor/start.sh" 2 minutes ago Up 2 minutes harbor-jobservice
794e29619d74 goharbor/harbor-portal:v1.7.0 "nginx -g 'daemon of?? 2 minutes ago Up 2 minutes (healthy) 80/tcp harbor-portal
1768ed74ea87 goharbor/harbor-core:v1.7.0 "/harbor/start.sh" 2 minutes ago Up 2 minutes (healthy) harbor-core
baa0ff5a77c8 goharbor/harbor-db:v1.7.0 "/entrypoint.sh post?? 3 minutes ago Up 2 minutes (healthy) 5432/tcp harbor-db
a4957591eb25 goharbor/harbor-registryctl:v1.7.0 "/harbor/start.sh" 3 minutes ago Up 2 minutes (healthy) registryctl
fae0c9ccf7bd goharbor/harbor-adminserver:v1.7.0 "/harbor/start.sh" 3 minutes ago Up 2 minutes (healthy) harbor-adminserver
82bda7680cce goharbor/redis-photon:v1.7.0 "docker-entrypoint.s?? 3 minutes ago Up 2 minutes 6379/tcp redis
acf4f076c2f4 goharbor/registry-photon:v2.6.2-v1.7.0 "/entrypoint.sh /etc?? 3 minutes ago Up 2 minutes (healthy) 5000/tcp registry
7e08dab0f44b goharbor/harbor-log:v1.7.0 "/bin/sh -c /usr/loc?? 3 minutes ago Up 3 minutes (healthy) 127.0.0.1:1514->10514/tcp
# 50. 可以看到数据也持久化在本地了
[root@www harbor]# ll /data/
total 8
drwxr-xr-x 2 root root 6 Aug 14 21:28 ca_download
drwxr-xr-x 2 10000 10000 6 Aug 14 21:28 config
drwx------ 19 polkitd ssh_keys 4096 Aug 14 21:28 database
drwxr-xr-x 2 10000 10000 6 Aug 14 21:27 job_logs
drwxr-xr-x 2 root root 6 Aug 14 21:28 psc
drwxr-xr-x 2 polkitd root 22 Aug 14 21:33 redis
drwxr-xr-x 3 10000 10000 20 Aug 14 10:11 registry
-rw------- 1 10000 10000 16 Aug 14 21:27 secretkey
lulei
, 并且设置密码, 并且绑定 library 仓库[root@localhost ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.179.100
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
这里告诉你了怎么推送镜像, 需要修改你的镜像 tag, 保持和下面提示的一致
[root@localhost ~]# docker tag nginx:latest 192.168.179.100/library/nginx
创建用户已经授予权限, 该用户是用于登入仓库验证并且上传镜像的用户 , 将之前创建的用户加入进去
使用上面的用户名提前登入(输入你的密码), 然后再去上传镜像
[root@localhost ~]# docker login 192.168.179.100/library/nginx
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
Login Succeeded
[root@localhost ~]# docker push 192.168.179.100/library/nginx
The push refers to repository [192.168.179.100/library/nginx]
f978b9ed3f26: Pushed
9040af41bb66: Pushed
7c7d7f446182: Pushed
d4cf327d8ef5: Pushed
13cb14c2acd3: Pushed
latest: digest: sha256:0efad4d09a419dc6d574c3c3baacb804a530acd61d5eba72cb1f14e1f5ac0c8f size: 1362
[root@localhost ~]# docker tag 02aedead27dd 192.168.179.100/library/tomcat:v1
[root@localhost ~]# docker push 192.168.179.100/library/tomcat:v1
下载你上传的镜像, 这里通过图形界面已经为我们提供了 push
命令, 点击然后在你的 shell 终端粘贴就行, 是不是很方便
[root@localhost ~]# docker rmi -f 2622e6cca7eb
[root@localhost ~]# docker pull 192.168.179.100/library/nginx:latest
latest: Pulling from library/nginx
8559a31e96f4: Already exists
8d69e59170f7: Already exists
3f9f1ec1d262: Already exists
d1f5ff4f210d: Already exists
1e22bfa8652e: Already exists
Digest: sha256:0efad4d09a419dc6d574c3c3baacb804a530acd61d5eba72cb1f14e1f5ac0c8f
Status: Downloaded newer image for 192.168.179.100/library/nginx:latest
192.168.179.100/library/nginx:latest
[root@localhost ~]# docker logout 192.168.179.100
Removing login credentials for 192.168.179.100
[root@localhost ~]# docker tag 688353a31fde 192.168.179.100/library/ansible/centos7-ansible
# 51. 退出之后, 如果需要上传镜像需要重新输入用户名密码, 可以看到只有登入才能上传镜像
[root@localhost ~]# docker push 192.168.179.100/library/ansible/centos7-ansible
The push refers to repository [192.168.179.100/library/ansible/centos7-ansible]
cf4eb7184a66: Preparing
596e51307fcb: Preparing
7794e20d52b7: Preparing
f8c414e271fb: Preparing
0d1585b29470: Preparing
34e7b85d83e4: Waiting
denied: requested access to the resource is denied
[root@localhost ~]# docker login 192.168.179.100
Username: lulei
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
Multi-stage builds are useful to anyone who has struggled to optimize Dockerfiles while keeping them easy to read and maintain.
With multi-stage builds, you use multiple FROM
statements in your Dockerfile. Each FROM
instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.
The following Dockerfile has two separate stages: one for building a binary, and another where we copy the binary into.
# 52. syntax=docker/dockerfile:1
FROM golang:1.21
WORKDIR /src
COPY <<EOF ./main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /bin/hello ./main.go
FROM scratch
COPY --from=0 /bin/hello /bin/hello
CMD ["/bin/hello"]
You only need the single Dockerfile. No need for a separate build script. Just run docker build
.
docker build -t hello .
The end result is a tiny production image with nothing but the binary inside. None of the build tools required to build the application are included in the resulting image.
How does it work? The second FROM
instruction starts a new build stage with the alpine:latest
image as its base. The COPY --from=0
line copies just the built artifact from the previous stage into this new stage. The Go SDK and any intermediate artifacts are left behind, and not saved in the final image.
By default, the stages aren’t named, and you refer to them by their integer number, starting with 0 for the first FROM
instruction. However, you can name your stages, by adding an AS <NAME>
to the FROM
instruction. This example improves the previous one by naming the stages and using the name in the COPY
instruction. This means that even if the instructions in your Dockerfile are re-ordered later, the COPY
doesn’t break.
# 53. syntax=docker/dockerfile:1
FROM golang:1.21 as build
WORKDIR /src
COPY <<EOF /src/main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /bin/hello ./main.go
FROM scratch
COPY --from=build /bin/hello /bin/hello
CMD ["/bin/hello"]
When you build your image, you don’t necessarily need to build the entire Dockerfile including every stage. You can specify a target build stage. The following command assumes you are using the previous Dockerfile
but stops at the stage named build
:
docker build --target build -t hello .
A few scenarios where this might be useful are:
debug
stage with all debugging symbols or tools enabled, and a lean production
stagetesting
stage in which your app gets populated with test data, but building for production using a different stage which uses real dataWhen using multi-stage builds, you aren’t limited to copying from stages you created earlier in your Dockerfile. You can use the COPY --from
instruction to copy from a separate image, either using the local image name, a tag available locally or on a Docker registry, or a tag ID. The Docker client pulls the image if necessary and copies the artifact from there. The syntax is:
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
You can pick up where a previous stage left off by referring to it when using the FROM
directive. For example:
# 54. syntax=docker/dockerfile:1
FROM alpine:latest AS builder
RUN apk --no-cache add build-base
FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp
FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp
The legacy Docker Engine builder processes all stages of a Dockerfile leading up to the selected --target
. It will build a stage even if the selected target doesn’t depend on that stage.
BuildKit only builds the stages that the target stage depends on.
For example, given the following Dockerfile:
# 55. syntax=docker/dockerfile:1
FROM ubuntu AS base
RUN echo "base"
FROM base AS stage1
RUN echo "stage1"
FROM base AS stage2
RUN echo "stage2"
With BuildKit enabled, building the stage2
target in this Dockerfile means only base
and stage2
are processed. There is no dependency on stage1
, so it’s skipped.
DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile --target stage2 .
[internal] load build definition from Dockerfile 0.0s
=> transferring dockerfile: 36B 0.0s
[internal] load .dockerignore 0.0s
=> transferring context: 2B 0.0s
[internal] load metadata for docker.io/library/ubuntu:latest 0.0s
CACHED [base 1/2] FROM docker.io/library/ubuntu 0.0s
[base 2/2] RUN echo "base" 0.1s
[stage2 1/1] RUN echo "stage2" 0.2s
exporting to image 0.0s
=> exporting layers 0.0s
=> writing image sha256:f55003b607cef37614f607f0728e6fd4d113a4bf7ef12210da338c716f2cfd15 0.0s
On the other hand, building the same target without BuildKit results in all stages being processed:
DOCKER_BUILDKIT=0 docker build --no-cache -f Dockerfile --target stage2 .
a7870fd478f4
Running in e850d0e42eca
d9f69f23cac8
Running in 758ba6c1a9a3
396baa55b8c3
d9f69f23cac8
Running in bbc025b93175
09fc3770a9c4
The legacy builder processes stage1
, even if stage2
doesn’t depend on it.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。