您现在的位置是:主页 > news > 公司网站找不到了/网页设计与制作软件有哪些

公司网站找不到了/网页设计与制作软件有哪些

admin2025/4/24 15:47:55news

简介公司网站找不到了,网页设计与制作软件有哪些,东莞做网站的公司,嘉兴网站制作怎么添加按钮1. 基础镜像的选择 尽量选择官方的镜像。没有官方镜像就尽量选择Dockerfile开源的尽量固定版本,不是每次都使用latest尽量选择体积小的镜像 2. 通过RUN执行命令 RUN主要是用于在Image内执行指令,比如安装软件、下载文件等。需要注意的每一行RUN命令都会产…

公司网站找不到了,网页设计与制作软件有哪些,东莞做网站的公司,嘉兴网站制作怎么添加按钮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 文件复制

往镜像复制文件有两种方式:COPYADD

  • COPYADD都可以把本地文件复制到镜像中(本地文件的权限同样会复制到镜像中),如果目标目录不存在则会自动创建。比如执行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

可以看到命令中出现了多次版本号,为了方便修改,需要设置变量。此时会使用到ARGENV。两者使用方式如下:

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

  1. CMD的作用和注意事项:

    • CMD可以用来设置容器启动时默认执行的命令

    • 如果docker container run启动容器时指定了其他命令,CMD命令会被忽略

    • 如果定义了多个CMD命令,只有最后一个会被执行

  2. 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

ENTRYPOINTCMD的区别:

  • CMD 设置的命令,可以在docker container run 时传入其它命令,覆盖掉 使用CMD 的命令,但是 ENTRYPOINT 所设置的命令是一定会被执行的
  • ENTRYPOINTCMD 可以联合使用,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格式

CMDENTRYPOINT都存在两种格式:

① 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 5000CMD ["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.pyDockerfile_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文件中进行以下修改:

  • 通过groupadduseradd创建一个组和用户
  • 通过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/