您现在的位置是:主页 > news > 公司网站找不到了/网页设计与制作软件有哪些
公司网站找不到了/网页设计与制作软件有哪些
admin2025/4/24 15:47:55【news】
简介公司网站找不到了,网页设计与制作软件有哪些,东莞做网站的公司,嘉兴网站制作怎么添加按钮1. 基础镜像的选择 尽量选择官方的镜像。没有官方镜像就尽量选择Dockerfile开源的尽量固定版本,不是每次都使用latest尽量选择体积小的镜像 2. 通过RUN执行命令 RUN主要是用于在Image内执行指令,比如安装软件、下载文件等。需要注意的每一行RUN命令都会产…
1. 基础镜像的选择
- 尽量选择官方的镜像。没有官方镜像就尽量选择Dockerfile开源的
- 尽量固定版本,不是每次都使用latest
- 尽量选择体积小的镜像
2. 通过RUN执行命令
RUN主要是用于在Image内执行指令,比如安装软件、下载文件等。需要注意的每一行RUN命令都会产生一层image layer,过多的RUN命令会导致镜像的臃肿。
比如当前目录下有Dockerfile_bad和Dockerfile_good两个文件,内容如下:
Dockerfile_bad:
FROM ubuntu:21.04 RUN apt-get update RUN apt-get install -y wget RUN wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz RUN tar zxf ipinfo_2.0.1_linux_amd64.tar.gz RUN mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo RUN rm -rf ipinfo_2.0.1_linux_amd64.tar.gz
Dockerfile_good:
FROM ubuntu:21.04 RUN apt-get update && \apt-get install -y wget && \wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz && \tar zxf ipinfo_2.0.1_linux_amd64.tar.gz && \mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo && \rm -rf ipinfo_2.0.1_linux_amd64.tar.gz
执行
docker image build -f Dockerfile_bad/Dockerfile_good -t ipinfo-bad/ipinfo-good .
命令后(-f 后加上需要使用的Dockerfile文件名称,'.'
表示执行的是当前目录下的Dockerfile文件),再通过docker image history 容器ID
命令查看两个镜像分层情况:
3. 文件的复制和目录操作
3.1 文件复制
往镜像复制文件有两种方式:
COPY
和ADD
COPY
和ADD
都可以把本地文件复制到镜像中(本地文件的权限同样会复制到镜像中),如果目标目录不存在则会自动创建。比如执行COPY hello.py /app/hello.py
,当/app
这个目录不存在就会自动创建。- 如果复制的是压缩文件,
ADD
会自动解压文件,COPY
不会。
3.2 目录操作
Dockerfile文件内容如下:
FROM python:3.9.5-alpine3.13 WORKDIR /app COPY hello.py hello.py
WORKDIR /app
相当于cd /app
,然后执行COPY
操作后就会把本地的hello.py
复制到/app
目录下。
4. 构建参数和环境变量
Dockerfile文件内容如下:
FROM ubuntu:21.04 RUN apt-get update && \apt-get install -y wget && \wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz && \tar zxf ipinfo_2.0.1_linux_amd64.tar.gz && \mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo && \rm -rf ipinfo_2.0.1_linux_amd64.tar.gz
可以看到命令中出现了多次版本号,为了方便修改,需要设置变量。此时会使用到
ARG
和ENV
。两者使用方式如下:Dockerfile-env:
FROM ubuntu:21.04 ENV VERSION=2.0.1 RUN apt-get update && \apt-get install -y wget && \wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
Dockerfile-arg:
FROM ubuntu:21.04 ARG VERSION=2.0.1 RUN apt-get update && \apt-get install -y wget && \wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
两者在上述代码中几乎没有区别,但是它们的作用范围是有一定区别的:
使用
ARG
创建的变量只能存在于构建镜像的时候,构建完镜像后该变量不会保存在镜像中,所以通过该镜像创建容器时也是无法使用该变量的。比如使用docker container run -it ipinfo-arg
创建容器并以交互式shell进行操作,此时使用env
命令查看环境变量时是没有VERSION
这个变量的。
ARG
创建的变量同样也有方便的地方:当使用Dockerfile-arg文件构建镜像时,可以使用docker image build -f Dockerfile-arg -t ipinfo-arg --build-arg VERSION=2.0.0 .
命令中修改ARG
,不需要再打开Dockerfile文件去修改ARG
变量
5. 容器启动命令CMD和ENTRYPOINT
5.1 CMD
CMD
的作用和注意事项:
CMD
可以用来设置容器启动时默认执行的命令如果
docker container run
启动容器时指定了其他命令,CMD
命令会被忽略如果定义了多个
CMD
命令,只有最后一个会被执行
CMD
的使用方式:
- 在dockerfile文件中添加。之后在创建容器后会执行
'ipinfo'
,而不是执行ubuntu
的基础镜像的'/bin/bash'
- 在创建容器时添加,比如
docker container run -it ipinfo-env ipinfo
FROM ubuntu:21.04 ENV VERSION=2.0.1 RUN apt-get update && \apt-get install -y wget && \wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz CMD ['ipinfo']
tips:
docker system prune -f
:快速清理所有退出的容器docker image prune -f
:快速清理所有没有使用的镜像- 使用第4节的Dockerfile-env文件构建镜像后,并输入
docker container run -it ipinfo-env
创建容器后,为什么会默认进入shell?因为在ubuntu
的基础镜像中,有一层执行了CMD ["/bin/bash"]
(可以通过docker image history ipinfo-env
进行查看层级)- 每次执行
docker container run -it ipinfo-env ipinfo
(创建容器并执行命令)后,就会出现一个退出的容器。可以将命令改为docker container run -rm -it ipinfo-env ipinfo
,这样执行完命令后就会删除该退出的容器
5.2 ENTRYPOINT
ENTRYPOINT
和CMD
的区别:
CMD
设置的命令,可以在docker container run
时传入其它命令,覆盖掉 使用CMD
的命令,但是ENTRYPOINT
所设置的命令是一定会被执行的ENTRYPOINT
和CMD
可以联合使用,ENTRYPOINT
设置执行的命令,CMD
传递参数假设有三个dockerfile文件:
Dockerfile_CMD:
FROM ubuntu:21.04 CMD ["echo", "hello docker"]
Dockerfile_ENTRYPOINT:
FROM ubuntu:21.04 ENTRYPOINT ["echo", "hello docker"]
Dockerfile_BOTH:
FROM ubuntu:21.04 ENTRYPOINT ["echo", "hello docker"] CMD []
使用
docker imgae build -f Dockerfile_CMD/ENTRYPOINT/BOTH -t cmd/entrypoint/both .
构建三个镜像:
执行
docker container run --rm -it cmd echo"hello cmd_test"
会显示hello cmd_test
而不是Dockerfile_CMD文件中的hello docker
执行
docker container run --rm -it entrypoint echo "hello enrtypoint_test"
会显示hello docker echo hello enrtypoint_test
,即Dockerfile_ENTRYPOINT文件中的内容执行了,并且命令行中的echo
作为参数传入,所以一同打印出来。这就印证了ENTRYPOINT
所设置的命令(文件中的echo
)是一定会被执行的执行
docker container run --rm -it both "hello both_test"
会显示hello both_test
。
5.3 Shell和Exec格式
CMD
和ENTRYPOINT
都存在两种格式:① Shell格式:
CMD echo "hello docker" ENTRYPOINT echo "hello docker"
② Exec格式:
CMD ["echo", "hello docker"] ENTRYPOINT ["echo", "hello docker"]
两者区别:
下面的书写是没有问题的:
FROM ubuntu:21.04 ENV NAME=docker CMD echo "hello $NAME"
但是改成Exec格式是不行的,下面会打印出
hello $NAME
不是hello docker
:FROM ubuntu:21.04 ENV NAME=docker CMD ["echo", "hello $NAME"]
要正常执行,需要以Shell脚本方式去执行:
FROM ubuntu:21.04 ENV NAME=docker CMD ["sh", "-c", "echo hello $NAME"]
6. 构建flask镜像
① 创建app.py文件:
from flask import Flaskapp = Flask(__name__)@app.route('/') def hello_world(): return 'Hello, World!'
② 创建Dockerfile_flask文件:
FROM python:3.9.5-slimCOPY app.py /src/app.pyRUN pip install flaskWORKDIR /src ENV FLASK_APP=app.pyEXPOSE 5000CMD ["flask", "run", "-h", "0.0.0.0"]
文件中的
EXPOSE 5000
和CMD ["flask", "run", "-h", "0.0.0.0"]
是为了可以在本机访问flask的web服务,后续会详细说明③ 创建镜像:输入
docker image build -f Dockerfile_flask -t flask_demo .
④ 创建容器:输入
docker container run -d -p 5000:5000 flask_demo
完成上述步骤后,本机输入
127.0.0.1:5000
就可以看到Hello World
7. Dockerfile的使用技巧
7.1 合理使用缓存
假设修改了第6节中app.py文件中的内容,此时要重新构建Dockerfile_flask文件,按理说不需要重新再去执行
pip install flak
等固定操作。但是实际情况下还是要重新去安装,这就没有使用到缓存。此时将文件改为:FROM python:3.9.5-slim RUN pip install flaskWORKDIR /src ENV FLASK_APP=app.pyCOPY app.py /src/app.pyEXPOSE 5000CMD ["flask", "run", "-h", "0.0.0.0"]
此时再去构建镜像时就可以使用缓存,因为在原始文件中,改变了app.py文件导致
COPY app.py /src/app.py
之后的命令都无法使用缓存。所以要将固定不变的命令(不是指命令不改变)写在文件前面
7.2 dockerignore
执行
docker image build -f Dockerfile_flask -t flask_demo .
构建镜像的时候会出现一个build context
:
可以看到是具有一定大小的,这个大小取决于当前目录下的文件有多少。因为在构建镜像指定了
'.'
,即本机当前目录,在执行COPY app.py /src/app.py
才知道app.py这个文件属于本机的哪个目录下,但此时当前目录下的文件也会发送给docker的服务端,导致构建速度变慢为了解决上述问题,可以使用
.dockerignore
文件,使用方式和.git
文件一样,将需要忽略的文件名写入该文件中即可假设当前目录下存在
app.py、Dockerfile_BOTH、Dockerfile_CMD、Dockerfile_ENTRYPOINT、Dockerfile_flask
,在构建镜像时,除了app.py
和Dockerfile_flak
其他文件并不需要,所以当前目录下创建.dockerignore
文件,将其他文件名写入到文件中,重新构建即可:
可以看出此时的
build context
已经减小了
7.3 多阶段构建
假如有一个
hello.c
的程序,要用Docker去做编译,然后执行可执行文件hello
:hello.c:
#include <stdio.h>void main(int argc, char *argv[]) {printf("hello %s\n", argv[argc - 1]); }
Dockerfile_gcc:
FROM gcc:9.4COPY hello.c /src/hello.cWORKDIR /srcRUN gcc --static -o hello hello.cENTRYPOINT [ "/src/hello" ]CMD []
使用
Dockerfile_gcc
构建镜像后会发现该镜像大约有1个多G(主要是基础镜像gcc的大小),但其实gcc镜像的作用只是运行RUN gcc --static -o hello hello.c
,即完成编译功能。后续执行/src/hello
是不需要gcc的环境的,在Linux系统下均可执行。这个时候可以使用多阶段构建:
Dockerfile_new:
FROM gcc:9.4 AS builderCOPY hello.c /src/hello.cWORKDIR /srcRUN gcc --static -o hello hello.cFROM alpine:3.13.5COPY --from=builder /src/hello /src/helloENTRYPOINT [ "/src/hello" ]CMD []
Dockerfile_new文件将原始的dockerfile文件分为编译和执行两个阶段。其中,
COPY --from=builder /src/hello /src/hello
表示将gcc镜像(builder)的指定目录下的hello
复制给alpine镜像下的指定目录。在构建新的镜像后,大小约为6M多(主要是基础镜像alpine的大小)
7.4 尽量使用非root用户
假如有一个用户demo,它本身不具有sudo的权限,所以就有很多文件无法进行读写操作,比如/root目录它是无法查看的,但是这个用户有执行docker的权限,也就是它在docker这个group里。因此就可以通过Docker做很多越权的事情了,比如可以把这个无法查看的/root目录映射到docker container里,此时可以自由进行查看了。
哪如何使用非root用户?可以在Dockerfile文件中进行以下修改:
- 通过
groupadd
和useradd
创建一个组和用户- 通过
USER
指定后面的命令要以指定用户的身份运行FROM python:3.9.5-slimRUN pip install flask && \groupadd -r flask && useradd -r -g flask flask && \mkdir /src && \chown -R flask:flask /srcUSER flaskCOPY app.py /src/app.pyWORKDIR /src ENV FLASK_APP=app.pyEXPOSE 5000CMD ["flask", "run", "-h", "0.0.0.0"]
8.参考
https://dockertips.readthedocs.io/en/latest/dockerfile-guide.html
https://github.com/docker-library/official-images
https://docs.docker.com/engine/reference/builder/