Docker-创建和分享应用(3)
Dockerfile
定义容器内环境中发生的事情。对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”哪些文件到该环境。但是,在执行此操作之后,您可以预期Dockerfile
在此处定义的应用程序的构建 在其运行的任何位置都完全相同。
1. 快速测试Docker环境是否可用#
1 | docker run hello-world |
2. 创建Dockerfile文件#
在一个空目录中创建一个名为Dockerfile的文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 使用官方的Python环境作为父镜像 FROM python # 设置工作目录为 /app WORKDIR / app # 拷贝当前目录下的文件到容器的/app目录下 COPY . / app # 在容器中运行下面命令安装 requirements.txt中的软件 RUN pip install - - trusted - host pypi.python.org - r requirements.txt # 暴露80端口到容器外部 EXPOSE 80 # 定义一个环境变量 ENV NAME World # 当容器启动时,运行'python app.py' CMD [ "python" , "app.py" ] |
3. 在该目录下继续创建一个Flask应用程序和安装文件清单#
app.py
#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host = "redis" , db = 0 , socket_connect_timeout = 2 , socket_timeout = 2 ) app = Flask(__name__) @app .route( "/" ) def hello(): try : visits = redis.incr( "counter" ) except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html. format (name = os.getenv( "NAME" , "world" ), hostname = socket.gethostname(), visits = visits) if __name__ = = "__main__" : app.run(host = '0.0.0.0' , port = 80 ) |
requirements.txt
#
1 2 | Flask Redis |
4. 构建应用程序#
我们准备构建应用程序。确保您仍处于新目录的顶层。这是ls
应该显示的内容:
1 2 | $ ls Dockerfile app.py requirements.txt |
创建一个Docker镜像,我们将使用该--tag或者-t
选项命名镜像
1 | docker build - - tag = friendlyhello . |
查看创建的镜像
1 2 3 | root@node1 docker] # docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE friendlyhello latest 67bd580f29b8 21 seconds ago 937MB |
Linux用户的故障排除
- 代理服务器设置
代理服务器可以在Web应用程序启动并运行后阻止其连接。如果您位于代理服务器后面,请使用以下ENV
命令将以下行添加到Dockerfile中,以指定代理服务器的主机和端口:
1 2 3 | # Set proxy server, replace host:port with values for your servers ENV http_proxy host:port ENV https_proxy host:port |
- DNS设置
DNS配置错误可能会产生问题pip
。您需要设置自己的DNS服务器地址才能pip
正常工作。您可能想要更改Docker守护程序的DNS设置。您可以/etc/docker/daemon.json
使用dns
密钥编辑(或创建)配置文件,如下所示:
1 2 3 | { "dns" : [ "your_dns_address" , "8.8.8.8" ] } |
在上面的示例中,列表的第一个元素是DNS服务器的地址。第二项是Google的DNS,可在第一项无法使用时使用。
在继续之前,请保存daemon.json
并重新启动docker服务。
sudo service docker restart
修复后,重试运行该build
命令。
5. 运行应用程序#
运行应用程序,使用以下方法将计算机的端口4000映射到容器的已发布端口80,-p是将容器的端口Publish到外部的意思。
1 | docker run - p 4000 : 80 friendlyhello |
在浏览器访问‘http://localhost:4000’即可访问到内部的应用程序,按Ctrl+c即可结束应用程序。
后台以分离模式运行应用程序,-d就是在后台运行镜像,并打印出容器ID
1 | docker run - d - p 4000 : 80 friendlyhello |
6. 停止应用程序所在容器的运行#
1 | docker container stop ID |
7. 分享镜像#
如果没有Docker帐户,请在hub.docker.com上注册一个帐户 ,并记下的用户名。
1. 在本地的计算机上登录
1 | docker login |
2. 将镜像打上标签,该命令的语法是:
1 | docker tag image username / repository:tag |
比如我的登录名为scottcho,将版本库命名为flask,tag为v1
1 2 3 4 5 | [root@node1 docker] # docker tag friendlyhello scottcho/flask:v1 [root@node1 docker] # docker image ls scottcho/flask REPOSITORY TAG IMAGE ID CREATED SIZE scottcho / flask v1 67bd580f29b8 30 minutes ago 937MB |
3. 发布镜像
1 | docker push scottcho / flask:v1 |
在docker hup上可以看见所创建的镜像
4. 在任何计算机上可以运行分享的镜像
如果映像在本地不可用,则Docker会从存储库中提取映像。
1 | docker run - p 4000 : 80 scottcho / flask:v1 |
查看容器内的改变信息
创建一个容器,会在容器的对应的镜像上增加一个可写层,镜像部分是只读的。通过 diff命令可以看出改变的信息。如:
[root@wls12c ~]$ docker run -i -t centos /bin/bash [root@224de7986c5f /]# touch demo.ext [root@224de7986c5f /]# echo hello docker >demo.ext [root@224de7986c5f /]# rm -rf anaconda-post.log [root@224de7986c5f /]# exit exit [root@wls12c ~]$ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 224de7986c5f centos "/bin/bash" 40 seconds ago Exited (0) 3 seconds ago desperate_curie [root@wls12c ~]$ docker diff 224d D /anaconda-post.log A /demo.ext C /root A /root/.bash_history
说明:每行代表一个变动的文件或目录。其中 A 表示新增、C表示被修改、D表示被删除
主机和容器之间的文件拷贝
容器--->主机
[root@wls12c ~]$ docker exec -t -i 9f bin/bash [root@9f49397623ad /]# cat demo.txt hello [root@9f49397623ad /]# exit exit
[root@wls12c ~]$ docker cp 9f:/demo.txt /test [root@wls12c ~]$ cat /test/demo.txt hello
主机-->容器
[root@wls12c ~]$ cp ~/1.txt /var/lib/docker/aufs/mnt/9f49397623ade7dfd2beb4d84454cbdb9878a4b22a2bab2e8b5db72bcffe60a0/test [root@wls12c ~]$ docker exec -t -i 9f /bin/bash [root@9f49397623ad /]# ls /test 1.txt
重命名容器
[root@wls12c ~]$ docker rename stoic_meitner demo
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
2015-08-24 Jar命令