当前位置 : 首页 » 文章分类 :  开发  »  Docker-使用

Docker-使用

Docker-使用


国内镜像加速

1ms.run

1、毫秒镜像
https://1ms.run/
docker pull docker.1ms.run/nginx:latest nginx:latest 替换成需要的镜像和版本
例如 docker pull docker.1ms.run/elastic/elasticsearch:8.18.1

小跟班

2、小跟班,镜像 dockerhub 网站
https://docker.xiaogenban1993.com/
docker pull docker.xiaogenban1993.com/nginx:latest nginx:latest 替换成需要的镜像和版本
例如 docker pull docker.xiaogenban1993.com/elastic/elasticsearch:8.18.1

dockerproxy

Docker 国内代理
https://dockerproxy.link/


Docker API

https://docs.docker.com/engine/api/sdk/examples/

containers/json 查看容器列表

curl --unix-socket /var/run/docker.sock http://localhost/v1.43/containers/json
[{
  "Id":"ae63e8b89a26f01f6b4b2c9a7817c31a1b6196acf560f66586fbc8809ffcd772",
  "Names":["/tender_wing"],
  "Image":"bfirsh/reticulate-splines",
  ...
}]

docker仓库

Red Hat
https://quay.io/repository/

Google
https://cloud.google.com/container-registry/

docker hub

Docker Hub 是由 Docker 公司负责维护的公共注册中心,包含大量的容器镜像,Docker 工具默认从这个公共镜像库下载镜像。
https://hub.docker.com/

推送镜像到 Docker Hub

1、注册 Docker Hub 账号

2、在命令行登录 Docker Hub 账号

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: masikkk
Password:
WARNING! Your password will be stored unencrypted in /home/centos/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

3、查看本地镜像

# 查看本地镜像
$ docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
masikkk/centos7-openjdk21             20240123            5996f993958f        7 weeks ago         720MB
masikkk/centos7-openjdk21-tesseract   20240123            15a6611140d7        40 hours ago        1.07GB

打镜像 tag 时需要注意名称中必须包含 Docker Hub 账号,我的账号是 masikkk,则镜像必须是 masikkk/ 开头,否则推送到 Docker Hub 时报错:

[centos@lightsail ~]$ docker push centos7-openjdk21
The push refers to repository [docker.io/library/centos7-openjdk21]
9441bde1b4e1: Preparing
0256674c5104: Preparing
174f56854903: Preparing
denied: requested access to the resource is denied

4、推送镜像到 Docker Hub

$ docker push masikkk/centos7-openjdk21:20240123
The push refers to repository [docker.io/masikkk/centos7-openjdk21]
9441bde1b4e1: Pushed
0256674c5104: Pushed
174f56854903: Pushed
20240123: digest: sha256:4707f90e6f702881dacd53a5480c129b8aca4baef6f6d2615a8243bda965d45d size: 954

Push the image
https://docs.docker.com/get-started/04_sharing_app/#push-the-image


docker-registry 私人仓库

library/registry 是官方提供的工具,可以用于构建私有的镜像仓库。也就是这个私人仓库程序本身就是一个镜像。
使用官方的 registry 镜像来启动私有仓库。
默认情况下,仓库会被创建在容器的 /var/lib/registry 目录下。
通过 -v 将本地目录 /home/centos/docker/registry 映射到容器的 /var/lib/registry 目录,这样上传到容器的镜像就保存到本地了。

$ docker run -d \
    -p 5000:5000 \
    --restart=always \
    --name registry \
    -v /home/centos/docker/registry:/var/lib/registry \
    registry

crane 镜像工具

crane 是一个与远程镜像和仓库交互的工具,由 Google containerregistry 开发

安装

# go 安装
go install github.com/google/go-containerregistry/cmd/crane@latest

# Mac
brew install crane

# bin
https://github.com/google/go-containerregistry/releases

命令

https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md

如果镜像仓库开启了用户认证,需要在使用之前先通过 crane auth login 登录:
crane auth login localhost:5000 -u admin -p passw0rd

将本地镜像内容推送到远程仓库
crane –insecure push myapp-1.2.1.tar localhost:5000/myapp:1.2.1

搭建自己的镜像仓库
https://www.aneasystone.com/archives/2022/09/build-your-own-image-registry.html


busybox 镜像

BusyBox 是一个集成了一百多个最常用 Linux 命令和工具(如 cat、echo、grep、mount、telnet 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证。


hexo 镜像

docker build -f centos7-openjdk21-nodejs16-hexo7.Dockerfile -t masikkk/centos7-openjdk21-node16-hexo7:20240317 .

docker run -d -it --rm \
-v ~/.ssh:/home/centos/.ssh \
masikkk/centos7-openjdk21-node16-hexo7:20240317 bash

后台启动容器,然后 docker exec 进入容器

根据 https://github.com/nodesource/distributions/tree/master?tab=readme-ov-file#rpm-supported-versions CentOS7最高只支持 nodejs 17,18及之上版本需要 CentOS8

安装git
sudo yum install -y git

git clone git@github.com:masikkk/hexo.git

安装 nodejs 17

curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
sudo yum install -y nodejs
# node -v
v17.9.0
# npm -v
8.5.5

Centos7-OpenJDK 镜像

nimmis/centos7-openjdk8 镜像

nimmis/java-centos
https://hub.docker.com/r/nimmis/java-centos/tags?page=1&name=openjdk-8

Dockerfile
https://github.com/nimmis/docker-java-centos/blob/master/openjdk-8-jdk/Dockerfile

只有amd64架构的

docker pull nimmis/java-centos:openjdk-8-jdk
REPOSITORY                                           TAG             IMAGE ID       CREATED          SIZE
nimmis/java-centos                                   openjdk-8-jdk   8a93794b15b0   5 years ago      402MB

AdoptOpenJDK/centos7-openjdk8 镜像

adoptopenjdk/openjdk8
https://hub.docker.com/r/adoptopenjdk/openjdk8/tags?page=1&name=centos

Dockerfile 文件
https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/8/jdk/centos/Dockerfile.hotspot.releases.full

AdoptOpenJDK 已被官方废弃,最高只到 jdk16
注意此镜像有多种架构,M1 Mac 上默认会拉取 arm64 架构的版本,如果想要使用 amd64/x86_64 架构版本,需要通过 --platform amd64 参数指定

docker pull adoptopenjdk/openjdk8:centos –platform amd64
docker pull adoptopenjdk/openjdk8:centos-slim –platform amd64

REPOSITORY TAG IMAGE ID CREATED SIZE
adoptopenjdk/openjdk8 centos-slim f7719a74b210 17 hours ago 471MB
adoptopenjdk/openjdk8 centos a72f04e4db6d 17 hours ago 579MB


自己构建 Centos7-OpenJDK8 镜像

1、创建 centos7-openjdk8.Dockerfile

FROM centos:7

MAINTAINER masikkk.com

RUN yum update -y && \
yum install -y wget && \
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel && \
yum clean all

# Set environment variables.
ENV HOME /root

# Define working directory.
WORKDIR /root

# Define default command.
CMD ["java","-version"]

2、构建镜像
进入 centos7-openjdk8.Dockerfile 文件所在目录
docker build -f centos7-openjdk8.Dockerfile -t masikkk/centos7-openjdk8:20240123 .
结果

$ docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
masikkk/centos7-openjdk8              20240123            a44b575730c8        56 seconds ago      602MB

3、运行镜像,由于 Dockerfile 里的 CMD 命令就是 java -version,执行 docker run 可直接看到 java 版本

$ docker run masikkk/centos7-openjdk8:20240123
openjdk version "1.8.0_392"
OpenJDK Runtime Environment (build 1.8.0_392-b08)
OpenJDK 64-Bit Server VM (build 25.392-b08, mixed mode)

也可以执行 docker run -it --rm centos7-openjdk8:20240123 bash 进入镜像看看 java 版本

4、推送到 Docker Hub

$ docker push masikkk/centos7-openjdk8:20240123
The push refers to repository [docker.io/masikkk/centos7-openjdk8]
ceb11fb82205: Pushed
174f56854903: Mounted from masikkk/centos7-openjdk21-tesseract
20240123: digest: sha256:93b85206411b507e869aeb841118b9bb23db26f53d3979a70c2f957b39fd244c size: 742

镜像已发布到 Docker Hub 公开仓库,可直接使用
https://hub.docker.com/repository/docker/masikkk/centos7-openjdk8


自己构建 CentOS7-OpenJDK21 镜像

注意:下面 docker 镜像的构建是在 linux 上执行的,如果在 M1 Mac 上打镜像但最后在 Linux 上跑,需要注意 M1 Mac 上默认会拉下来 arm64 架构的镜像,而 Linux 上需要 amd64 架构的镜像。

1、创建 centos7-openjdk21.Dockerfile

# 自己基于CentOS7构建带JDK8的镜像
FROM centos:7

MAINTAINER masikkk.com

# 更新yum,安装wget
RUN yum update -y && \
    yum install -y wget && \
    yum clean all

# https://jdk.java.net/21/
RUN mkdir -p /opt/java && \
    cd /opt/java && \
    wget https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz && \
    tar -xf openjdk-21.0.1_linux-x64_bin.tar.gz && \
    rm -rf openjdk-21.0.1_linux-x64_bin.tar.gz

# Set environment variables.
ENV JAVA_HOME /opt/java/jdk-21.0.1
ENV PATH $PATH:$JAVA_HOME/bin

# Define default command.
CMD ["java","-version"]

2、进入 centos7-openjdk21.Dockerfile 所在目录,执行:

docker build -f centos7-openjdk21.Dockerfile  -t masikkk/centos7-openjdk21:20240123 .

结果:

$ docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED
masikkk/centos7-openjdk21             20240123            5996f993958f        7 weeks ago         720MB

3、执行 docker run masikkk/centos7-openjdk21:20240123 验证,由于 Dockerfile 里的 CMD 命令就是 java -versiondocker run 可直接看到 java 版本

$ docker run masikkk/centos7-openjdk21:20240123
openjdk version "21.0.1" 2023-10-17
OpenJDK Runtime Environment (build 21.0.1+12-29)
OpenJDK 64-Bit Server VM (build 21.0.1+12-29, mixed mode, sharing)

也可以 docker run -it --rm masikkk/centos7-openjdk21:20240123 bash 进入容器验证
或者 docker run -d -it --rm masikkk/centos7-openjdk21:20240123 bash 后台启动容器,然后 docker exec 进入容器。

4、推送到 Docker Hub

$ docker push masikkk/centos7-openjdk21:20240123
The push refers to repository [docker.io/masikkk/centos7-openjdk21]
9441bde1b4e1: Pushed
0256674c5104: Pushed
174f56854903: Pushed
20240123: digest: sha256:4707f90e6f702881dacd53a5480c129b8aca4baef6f6d2615a8243bda965d45d size: 954

镜像已发布到 Docker Hub 公开仓库,可直接使用
https://hub.docker.com/repository/docker/masikkk/centos7-openjdk21/general


自己构建 CentOS7-OpenJDK21-Maven3.9 镜像

注意:下面 docker 镜像的构建是在 linux 上执行的,如果在 M1 Mac 上打镜像但最后在 Linux 上跑,需要注意 M1 Mac 上默认会拉下来 arm64 架构的镜像,而 Linux 上需要 amd64 架构的镜像。

1、创建 centos7-openjdk21-maven.Dockerfile 文件

# 自己基于 CentOS7 构建带 JDK21 和 Maven 镜像
FROM centos:7

MAINTAINER masikkk.com

# CentOS7 已经停止维护,改为阿里云镜像源,更新yum,安装wget
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo && \
    sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://mirrors.aliyun.com|g' /etc/yum.repos.d/CentOS-*.repo && \
    yum update -y && \
    yum install -y wget && \
    yum clean all

# https://jdk.java.net/21/
RUN mkdir -p /opt/java && \
    cd /opt/java && \
    wget https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz && \
    tar -xf openjdk-21.0.1_linux-x64_bin.tar.gz && \
    rm -rf openjdk-21.0.1_linux-x64_bin.tar.gz

# Set environment variables.
ENV JAVA_HOME /opt/java/jdk-21.0.1
ENV PATH $PATH:$JAVA_HOME/bin

# 安装 Maven
RUN mkdir -p /opt/maven && \
    cd /opt/maven && \
    wget https://archive.apache.org/dist/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz && \
    tar -xf apache-maven-3.9.6-bin.tar.gz && \
    rm -rf apache-maven-3.9.6-bin.tar.gz

# Set Maven environment variables
ENV MAVEN_HOME /opt/maven/apache-maven-3.9.6
ENV PATH $PATH:$MAVEN_HOME/bin

# Define default command.
CMD ["mvn","-version"]

2、进入 centos7-openjdk21-maven.Dockerfile 文件所在目录,执行

docker build -f centos7-openjdk21-maven.Dockerfile  -t masikkk/centos7-openjdk21-maven3.9:20250805 .

3、执行 docker run masikkk/centos7-openjdk21-maven3.9:20250805 由于 Dockerfile 里的 CMD 命令是 mvn -version 可直接看到 mvn 版本号输出:

$ docker run masikkk/centos7-openjdk21-maven3.9:20250805
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /opt/maven/apache-maven-3.9.6
Java version: 21.0.1, vendor: Oracle Corporation, runtime: /opt/java/jdk-21.0.1
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.1.3.el7.x86_64", arch: "amd64", family: "unix"

4、推送到 Docker Hub

docker push masikkk/centos7-openjdk21-maven3.9:20250805
The push refers to repository [docker.io/masikkk/centos7-openjdk21-maven3.9]
a734edfd26b7: Pushed
e5abc25c70ad: Pushed
41092b8e21e5: Pushed
174f56854903: Mounted from masikkk/centos7-openjdk8
20250805: digest: sha256:0122ef65fc250355ac7a42c88d90d2484ee55d7aed2678107f7bf5a25a631cd2 size: 1165

镜像已发布到 Docker Hub 公开仓库,可直接使用
https://hub.docker.com/repository/docker/masikkk/centos7-openjdk21-maven3.9/general


自己构建 CentOS7-OpenJDK21-tesseract 镜像

1、创建 centos7-openjdk21-tesseract.Dockerfile

# 基于自己构建的 Centos7-OpenJDK21 镜像
FROM masikkk/centos7-openjdk21:20240123

MAINTAINER masikkk.com

# 更新yum,安装wget
RUN yum update -y && \
    yum install -y wget && \
    yum clean all


# 安装 tesseract,加 --nogpgcheck 忽略公钥检查
RUN yum-config-manager --add-repo http://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/RHEL_7/ && \
    yum update -y && \
    yum install tesseract -y --nogpgcheck

# 容器默认命令
CMD ["tesseract","-v"]

2、进入 centos7-openjdk21-tesseract.Dockerfile 所在目录,执行:

docker build -f centos7-openjdk21-tesseract.Dockerfile -t masikkk/centos7-openjdk21-tesseract:20240123 .

结果:

$ docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
masikkk/centos7-openjdk21-tesseract   20240123            15a6611140d7        40 hours ago        1.07GB

3、执行 docker run masikkk/centos7-openjdk21-tesseract:20240123 由于 CMD 默认命令是 tesseract -v,可直接看到 tesseract 版本号:

$ docker run masikkk/centos7-openjdk21-tesseract:20240123
tesseract 4.1.3
 leptonica-1.76.0
  libjpeg 6b (libjpeg-turbo 1.2.90) : libpng 1.5.13 : libtiff 4.0.3 : zlib 1.2.7 : libwebp 0.3.0
 Found AVX2
 Found AVX
 Found FMA
 Found SSE

也可以 docker run -it --rm masikkk/centos7-openjdk21-tesseract:20240123 bash 进入容器验证。

4、推送到 Docker Hub

$ docker push masikkk/centos7-openjdk21-tesseract:20240123
The push refers to repository [docker.io/masikkk/centos7-openjdk21-tesseract]
0dcffa355b31: Pushed
ce751aba1cc4: Pushed
9441bde1b4e1: Mounted from masikkk/centos7-openjdk21
0256674c5104: Mounted from masikkk/centos7-openjdk21
174f56854903: Mounted from masikkk/centos7-openjdk21
20240123: digest: sha256:cf72104eac31f86e2a082d7c13205ef697b5bddd841c3ab27823b1078d3420ce size: 1379

镜像已发布到 Docker Hub 公开仓库,可直接使用
https://hub.docker.com/repository/docker/masikkk/centos7-openjdk21-tesseract/general


Docker 构建部署 SpringBoot 服务

Spring Boot with Docker
https://spring.io/guides/gs/spring-boot-docker/

docker hub / openjdk
https://hub.docker.com/_/openjdk

构建基于 openjdk:8-alpine 的 SpringBoot 服务镜像

1、在项目根目录下添加 Dockerfile 文件:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
RUN apk add --no-cache tzdata \
 && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asia/shanghai" > /etc/timezone \
 && rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache ## 清除缓存
ENTRYPOINT ["java","-jar","/app.jar"]

由于 alpine 中是 UTC 时区,需要改为东八区,但 alpine 中默认又没有 /usr/share/zoneinfo/Asia/Shanghai 时区文件,只能先安装时区文件 tzdata,再链接到 /etc/localtime

2、先用 maven 把 spring boot 项目打包为可运行的 jar 包
mvn package

3、构建 SpringBoot Docker 镜像
在 Dockerfile 所在的项目根目录下 构建镜像 docker build -t blog-server .
注意一定要在 Dockerfile 所在的目录,最后那个 . 指定了当前目录是构建上下文。

$ docker build -t blog-server .
Sending build context to Docker daemon  117.6MB
Step 1/6 : FROM openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/6 : VOLUME /tmp
 ---> Using cache
 ---> d0ee8c49a7f7
Step 3/6 : ARG JAR_FILE=target/*.jar
 ---> Using cache
 ---> 8db784deccb1
Step 4/6 : COPY ${JAR_FILE} app.jar
 ---> 506e8cf80e06
Step 5/6 : RUN apk add --no-cache tzdata  && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  && echo "Asia/shanghai" > /etc/timezone  && rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache ## 清除缓存
 ---> Running in 74f8c63c1c21
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2020c-r1)
Executing busybox-1.29.3-r10.trigger
OK: 107 MiB in 55 packages
Removing intermediate container 74f8c63c1c21
 ---> 8686579ddbe7
Step 6/6 : ENTRYPOINT ["java","-jar","/app.jar"]
 ---> Running in acacc24c7c34
Removing intermediate container acacc24c7c34
 ---> b6c2b7ac458f
Successfully built b6c2b7ac458f
Successfully tagged blog-server:latest

4、查看构建好的镜像 docker images

$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
blog-server               latest              b6c2b7ac458f        37 seconds ago      224MB

构建基于 centos7-openjdk8 的 SpringBoot 服务镜像

1、准备 Dockerfile 文件

# https://hub.docker.com/r/adoptopenjdk/openjdk8/tags?page=1&name=centos
# https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/8/jdk/centos/Dockerfile.hotspot.releases.full
FROM adoptopenjdk/openjdk8:centos

VOLUME /tmp

MAINTAINER masikkk.com

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ARG JAR_FILE=blog-server/target/blog-server.jar
COPY ${JAR_FILE} /blog-server.jar

ENTRYPOINT ["java","-jar","/blog-server.jar"]

2、构建镜像
我在 M1 Mac 上默认会构建 “Architecture”: “arm64” 架构的镜像,为了能在 Linux 上复用,通过 --platform=amd64 指定构建 amd64/x86_64 架构的镜像
docker build -f blog.Dockerfile –platform=amd64 -t blog .


启动 SpringBoot Docker 容器

linux 中启动 SpringBoot Docker 容器

docker run -d --rm \
--network host \
--name blog-server \
-v /var/log/spring:/var/log/spring \
-e "SPRING_PROFILES_ACTIVE=local" \
blog-server

解释下

  • 以 host 网络模式启动容器,和宿主机完全共享网络,不需要再配置 -p 端口映射
  • 我的业务日志写到了 /data/log/spring 目录中,通过 -v 映射到本地
  • -e "SPRING_PROFILES_ACTIVE=local" 指定启动spring的profile

启动后进入容器 docker exec -it blog-server sh
查看系统版本

# cat os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.9.4
PRETTY_NAME="Alpine Linux v3.9"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

Mac 上启动 SpringBoot Docker 容器

Mac 上启动,由于 mac 中没有 host 网络,需要 -p 指定端口映射

docker run -d --rm \
-p 8001:8001 \
--name blog \
-v /var/log/spring:/var/log/spring \
-e "SPRING_PROFILES_ACTIVE=local" \
blog

M1 Mac 上运行 amd64/x86_64 架构镜像

docker run -d --rm \
--platform linux/amd64 \
-p 8001:8001 \
--name blog \
-v /var/log/spring:/var/log/spring \
-e "SPRING_PROFILES_ACTIVE=local" \
blog

Docker 容器部署 Nginx

docker hub 的 nginx 官方页面里有比较全面的用法
https://hub.docker.com/_/nginx

Nginx 容器教程
https://www.ruanyifeng.com/blog/2018/02/nginx-docker.html

拉取最新 alpine 版本 Nginx 镜像

如果不带标签的话,默认拉取的是 latest 版本镜像,也就是 1.17.9, mainline, 1, 1.17, latest,这个版本用的是 debian:buster-slim linux ,不是很习惯,好多基本命令没有。
所以加上 alpine 标签拉取 1.17.9-alpine, mainline-alpine, 1-alpine, 1.17-alpine, alpine 版本镜像

拉取官方 nginx alpine 版本镜像的最新版 docker pull nginx:alpine

$ docker pull nginx:alpine
alpine: Pulling from library/nginx
4167d3e14976: Pull complete
bb292c78f105: Pull complete
Digest: sha256:abe5ce652eb78d9c793df34453fddde12bb4d93d9fbf2c363d0992726e4d2cad
Status: Downloaded newer image for nginx:alpine
docker.io/library/nginx:alpine

启动默认 nginx:alpine 镜像

启动默认 nginx 容器
docker run -d -p 80:80 --name my-nginx --rm nginx:alpine
也可以不先拉取 nginx 镜像,启动时自动从 docker hub 拉取最新版 nginx 镜像。

进容器中查看系统版本
查看 /etc/os-release 文件

# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.10.4
PRETTY_NAME="Alpine Linux v3.10"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

nginx 版本

# nginx -v
nginx version: nginx/1.17.9

配置目录
/etc/nginx/nginx.conf
日志目录
/var/log/nginx/error.log
/var/log/nginx/access.log


指定配置文件启动 nginx:alpine

还使用原始的 nginx:alpine 官方镜像,只不过在启动命令中加入自己的配置,很方便

aws 上的nginx

docker run -d --rm \
--network host \
--name nginx \
-e TZ="Asia/Shanghai" \
-v /home/centos/git/hexo/nginx/nginx-centos.conf:/etc/nginx/nginx.conf:ro \
-v /home/centos/git/hexo/public:/home/centos/git/hexo/public \
-v /home/centos/git/image:/home/centos/git/image \
-v /var/log/nginx:/var/log/nginx \
nginx:alpine

解释:

  • 以 host 网络模式启动容器,和宿主机完全共享网络,不需要再配置 -p 端口映射,否则容器内的 nginx 需要配置主机 ip 才能访问主机网络。
  • 容器中默认是 UTC 时区,比我们的时间慢8小时,改为 Asia/Shanghai 即东八区
  • 文件和文件夹映射
  • 把本地的 nginx 配置文件 /home/centos/git/hexo/nginx/nginx-centos.conf 映射到容器中的 /etc/nginx/nginx.conf,会自动覆盖容器的配置文件,注意必须用绝对路径。这两个文件可以不同名。
  • 把静态文件目录 /home/centos/git/hexo/public 映射到容器中的同名目录,由于容器中没有这个目录,会自动新建并将全部内容拷贝进去,而且,以后宿主机此文件夹的更新会完全反应到容器中。
  • 把图片文件目录 /home/centos/git/hexo/image 映射到容器中的同名目录,由于容器中没有这个目录,会自动新建并将全部内容拷贝进去,而且,以后宿主机此文件夹的更新会完全反应到容器中。
  • 把容器中 nginx 的日志目录 /var/log/nginx 映射到本机的同名目录,由于本机没有 /var/log/nginx 目录,会自动创建,之后在本机即可看 nginx 日志
  • --rm 表示停止容器时删除容器文件,因为 nginx 是无状态的即开即用服务,且配置文件和静态文件映射自宿主机文件,容器内不需要任何持久化,停止后删掉就行,下次再重新启动一个新容器。
  • --name nginx 指定一个容器名,方便之后的操作

构建自己的 nginx 镜像并启动

在 nginx-centos.conf 文件所在的目录中新建 Dockerfile 文件

FROM nginx:alpine
COPY nginx-centos.conf /etc/nginx/nginx.conf
RUN echo "Asia/shanghai" > /etc/timezone \
 && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

解释:

  • 基础镜像是 alpine 版本最新 nginx
  • 把自己的配置文件 nginx-centos.conf 拷贝到容器中覆盖默认的 /etc/nginx/nginx.conf
  • 修改容器的时区

在 Dockerfile 所在目录内执行
docker build -t nginx-masikkk . 构建自己的 nginx 镜像,名为 nginx-masikkk, 以当前路径为上下文路径
一定要注意上下文路径是当前所在文件夹,所以 COPY 指令才可以直接拷贝当前文件夹中的 nginx-centos.conf 文件

$ docker build -t nginx-masikkk .
Sending build context to Docker daemon  15.87kB
Step 1/3 : FROM nginx
latest: Pulling from library/nginx
Digest: sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Status: Downloaded newer image for nginx:latest
 ---> 231d40e811cd
Step 2/3 : COPY nginx-centos.conf /etc/nginx/nginx.conf
 ---> e45c37eea53f
Step 3/3 : RUN echo "Asia/shanghai" > /etc/timezone  && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
 ---> Running in f8cc0a26834a
Removing intermediate container f8cc0a26834a
 ---> 20ad396f30ea
Successfully built 20ad396f30ea
Successfully tagged nginx-masikkk:latest

查看构建好的镜像

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx-masikkk       latest              20ad396f30ea        4 seconds ago       126MB
nginx               latest              231d40e811cd        4 weeks ago         126MB

启动自己的 nginx 容器

docker run -d --rm \
--network host \
--name nginx \
-v /home/centos/git/hexo/public:/home/centos/git/hexo/public \
-v /home/centos/git/hexo/image:/home/centos/git/hexo/image \
-v /var/log/nginx:/var/log/nginx \
nginx-masikkk

这样启动命令可以少两个参数。


nginx.conf 中的用户名必须是 nginx

docker 版 nginx 默认以用户 nginx 启动,一开始我使用了自己当前的用户,一直无法启动
报错
2019/12/23 03:49:40 [emerg] 1#1: getpwnam(“centos”) failed in /etc/nginx/nginx.conf:2
nginx: [emerg] getpwnam(“centos”) failed in /etc/nginx/nginx.conf:2
在 nginx.conf 中改为 user nginx nginx; 后好了


Docker 容器部署 Prometheus

INSTALLATION
https://prometheus.io/docs/prometheus/latest/installation/

docker 太方便了,准备好配置文件后直接启动就行,自动从 dockerhub 拉取最新官方镜像,我的启动命令如下:

docker run -d --rm \
--network host \
--name prometheus \
-v /home/centos/git/spring-boot-masikkk/devops/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /data/prometheus:/prometheus \
prom/prometheus

解释下:
-d 后台运行
--rm 停止容器后删掉容器文件
--network host 与宿主机完全共享网络,默认是bridge桥接,无法在nginx中通过localhost转发请求。默认是 9090 端口
--name prometheus 指定启动的容器名,方便按名称stop等操作
-v 映射配置文件,具体说是宿主机配置文件覆盖容器中的配置文件,我的配置文件在 git 仓库中,方便保存,也可以记录修改历史。
-v /data/prometheus:/prometheus 映射数据目录,持久化容器数据,注意宿主机 /data/prometheus 目录要给容器内用户开写权限,否则启动失败
参考笔记 Prometheus


Docker 容器部署 Grafana

Installing Grafana
https://grafana.com/docs/grafana/latest/installation/

Installing using Docker
https://grafana.com/docs/grafana/latest/installation/docker/

第一次执行时直接从 dockerhub 拉取最新版本 grafana

docker run -d --rm \
--network host \
--name grafana \
grafana/grafana

解释下:
-d 后台运行
--rm 停止容器后删掉容器文件
--network host 与宿主机完全共享网络,默认是bridge桥接,无法在nginx中通过localhost转发请求
--name grafana 指定启动的容器名,方便按名称stop等操作

参考笔记 Grafana


docker容器部署邮件服务器

tomav/docker-mailserver
https://github.com/tomav/docker-mailserver

tvial/docker-mailserver
https://hub.docker.com/r/tvial/docker-mailserver

利用Docker自建多功能加密邮件服务器
https://www.itmanbu.com/docker-mail-server.html

Mail Server Docker
https://blog.liyang.info/2018/04/17/mail-server-docker/


遇到的问题

容器内的nginx无法访问宿主机网络

我在宿主机上用 nodejs 起了个 http 服务器做 git webhooks,监听 1121 端口,在容器内的 nginx 要把访问 1121 端口的请求转发到宿主机上,是这么写的配置

# webhooks.开头的三级域名访问, git的webhooks, 转发到后台 node.js web服务
server {
    listen       80;
    server_name  webhooks.devgou.com webhooks.madaimeng.com webhooks.masikkk.com;
    location / {
            proxy_pass http://localhost:1121;
    }
}

访问 webhooks 接口的时候报错 502 Bad Gateway, nginx 日志报错

2019/12/25 10:52:31 [error] 6#6: *1892 connect() failed (111: Connection refused) while connecting to upstream, client: 220.194.45.154, server: webhooks.devgou.com, request: "GET /pull/hexo HTTP/1.1", upstream: "http://127.0.0.1:1121/pull/hexo", host: "webhooks.devgou.com"
220.194.45.154 - - [25/Dec/2019:10:52:31 +0800] "GET /pull/hexo HTTP/1.1" 502 559 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
2019/12/25 10:52:32 [error] 6#6: *1892 no live upstreams while connecting to upstream, client: 220.194.45.154, server: webhooks.devgou.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://localhost/favicon.ico", host: "webhooks.devgou.com", referrer: "http://webhooks.devgou.com/pull/hexo"

也就是找不到 localhost:1121 服务,想了想也是, 容器和宿主机是两个系统,容器的 localhost 和宿主机不同,肯定找不到这个服务。
下面就是解决如何在容器中访问宿主机的网络了

方法一,bridge网络模式的容器使用宿主机在docker0网卡上的ip访问宿主机。
安装 Docker 的时候,会在宿主机安装一个虚拟网卡 docker0, 它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
在宿主机上 ifconfig 查看 docker0 网卡的ip地址,Linux下一般是 172.17.0.1 , macOS下一般是 192.168.65.1,并不固定。
在容器中使用宿主机ip访问的问题是,配置写死ip非常不灵活,和docker anywhere deploy 的原则相悖。

方法二,使用host宿主机网络模式启动容器
Docker容器运行的时候有 host 、 bridge 、 none 三种网络可供配置。默认是 bridge ,即桥接网络,以桥接模式连接到宿主机; host 是宿主网络,即与宿主机共用网络; none 则表示无网络,容器将无法联网。

当容器使用 host 网络时,容器与宿主共用网络,这样就能在容器中访问宿主机网络,那么容器的 localhost 就是宿主机的 localhost 。
启动容器时加参数 --network host 表示已宿主机网络模式启动容器。此时不需要-p 80:80做端口映射了,因为本身与宿主机共用了网络,容器中暴露端口等同于宿主机暴露端口。
这种模式的问题是破坏了容器之间的隔离性,好处是网络访问很方便。

Docker容器访问宿主机网络的方法
https://m.jb51.net/article/149173.htm


查看容器中的日志

容器中的 nginx 日志文件都重定向到了重启的标准输出和标准错误输出,所以直接到容器中看 access.log 是没有内容的。
有如下两个方法看日志:
1、可以在容器外通过 docker logs -f nginx-name 查看日志
/var/log/nginx/access.log -> /dev/stdout
/var/log/nginx/error.log -> /dev/stderr

2、启动容器时 -v /var/log/nginx:/var/log/nginx 将容器内日志目录映射到本机,之后直接在本机即可看日志。


alpine镜像中jvm工具不可用问题

在alpine镜像中使用诸如jstack,jinfo工具,有如下报错:
1: Unable to get pid of LinuxThreads manager thread

原因是pid为1,发现PID为1的时候,工具不可用。

解决:
1、Dockerfile里使用如下命令启动:
CMD ["/bin/sh","-c","java APP","&& 1"]
2、或者使用 --init 参数来启动docker


docker启动java服务报错 Failed to start thread “GC Thread#0”

docker 启动 springboot java 服务报错:

[0.007s][warning][os,thread] Failed to start thread "GC Thread#0" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create worker GC thread. Out of system resources.
# An error report file with more information is saved as:
# //hs_err_pid7.log

解决:
docker 启动命令添加参数 --privileged 特权模式

https://github.com/halo-dev/halo/issues/2503
https://github.com/adoptium/temurin-build/issues/2976


java.lang.UnsatisfiedLinkError: no fontmanager in java.library.path

某些需要绘制图表的 java 应用在 docker 中可能遇到这个问题,比如需要创建 excel 表格的,原因是缺少字体配置。

no fontmanager in java.library.path
https://stackoverflow.com/questions/37251309/no-fontmanager-in-java-library-path/39861372

java.lang.UnsatisfiedLinkError: no fontmanager in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:61)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32)
at sun.font.SunFontManager$1.run(SunFontManager.java:339)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.SunFontManager.<clinit>(SunFontManager.java:335)

修改容器时区

多数容器中默认是 Etc/UTC UTC 时区

可以进入容器修改时区,不推荐
docker exec -it <CONTAINER NAME> bash
echo "Asia/Shanghai" > /etc/timezone

启动容器时用环境变量TZ指定时区
docker run -e TZ="Asia/Shanghai" -d -p 80:80 --name nginx nginx

启动容器时-v绑定主机时区文件
利用 volume 可以在启动一个 container 时指定使用主机的时区文件,就可以把 container 的时区与主机同步
docker run -v /etc/localtime:/etc/localtime <IMAGE:TAG>

Dockerfile中指定时区

如果是打包自己的镜像,可以在 Dockerfile 中增加

RUN echo "Asia/shanghai" > /etc/timezone \
 && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

前提是容器的linux中本身就有 /usr/share/zoneinfo/Asia/Shanghai 时区文件

基于alpine的镜像中修改时区

alpine 中默认也是 UTC 时区,需要改为东八区,但 alpine 中默认又没有 /usr/share/zoneinfo/Asia/Shanghai 时区文件,只能先安装时区文件 tzdata,再链接到 /etc/localtime

RUN apk add --no-cache tzdata \
 && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asia/shanghai" > /etc/timezone \
 && rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache ## 清除缓存

Mac中使用docker时遇到的问题

mac中映射的文件需要先设置共享

Mac docker 中启动时报错
docker: Error response from daemon: Mounts denied:
The path /var/log/spring
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences… -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

因为通过 -v 映射了一个不在共享配置中的文件夹

Mac 系统中想要和容器共享文件夹的话,需要先配置
默认已共享了 /Users/, /Volumes/, /private/, and /tmp
可在 Preferences -> File sharing 中增加共享目录

mac上宿主机和容器互相网络访问

mac中没有docker0虚拟网卡
受限于 Docker Desktop for Mac 底层的网络实现, Mac上的docker没有 docker0 网卡。

从容器中访问mac网络的方法
通过调试用DNS host.docker.internal

从mac上访问容器网络的方法:
使用 -p 80:80 暴露端口, --network host 不起作用

host 类型网络只能在 Linux 上使用, 在 Mac 和 Windows 上不支持。
https://docs.docker.com/network/host/
The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.

https://docs.docker.com/docker-for-mac/networking/


M1 Mac 上构建和运行 amd64/x86_64 架构镜像

为了在 M1 Mac 上模拟运行 amd64/x86_64 架构的 Linux 环境,需要构建和运行 amd64/x86_64 架构镜像。

1、M1 Mac 上构建 amd64/x86_64 架构镜像
docker build -f devops/blog.Dockerfile –platform=amd64 -t blog .

2、M1 Mac 上运行 amd64/x86_64 架构镜像,可以指定 --platform linux/amd64 参数

docker run -d --rm \
--platform linux/amd64 \
-p 8001:8001 \
--name blog \
-v /var/log/spring:/var/log/spring \
-e "SPRING_PROFILES_ACTIVE=local" \
blog

如果镜像本身是 amd64/x86_64 架构的,不需要指定,但 docker run 会报警告:
WARNING: The requested image’s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested


上一篇 Python-基础

下一篇 Linux上搭建邮件服务器

阅读
评论
7.3k
阅读预计35分钟
创建日期 2019-08-12
修改日期 2025-08-05
类别
目录
  1. 国内镜像加速
    1. 1ms.run
    2. 小跟班
    3. dockerproxy
  2. Docker API
    1. containers/json 查看容器列表
  3. docker仓库
    1. docker hub
      1. 推送镜像到 Docker Hub
    2. docker-registry 私人仓库
  4. crane 镜像工具
    1. 安装
    2. 命令
  5. busybox 镜像
  6. hexo 镜像
  7. Centos7-OpenJDK 镜像
    1. nimmis/centos7-openjdk8 镜像
    2. AdoptOpenJDK/centos7-openjdk8 镜像
    3. 自己构建 Centos7-OpenJDK8 镜像
    4. 自己构建 CentOS7-OpenJDK21 镜像
    5. 自己构建 CentOS7-OpenJDK21-Maven3.9 镜像
    6. 自己构建 CentOS7-OpenJDK21-tesseract 镜像
  8. Docker 构建部署 SpringBoot 服务
    1. 构建基于 openjdk:8-alpine 的 SpringBoot 服务镜像
    2. 构建基于 centos7-openjdk8 的 SpringBoot 服务镜像
    3. 启动 SpringBoot Docker 容器
      1. linux 中启动 SpringBoot Docker 容器
      2. Mac 上启动 SpringBoot Docker 容器
  9. Docker 容器部署 Nginx
    1. 拉取最新 alpine 版本 Nginx 镜像
    2. 启动默认 nginx:alpine 镜像
    3. 指定配置文件启动 nginx:alpine
    4. 构建自己的 nginx 镜像并启动
    5. nginx.conf 中的用户名必须是 nginx
  10. Docker 容器部署 Prometheus
  11. Docker 容器部署 Grafana
  12. docker容器部署邮件服务器
  13. 遇到的问题
    1. 容器内的nginx无法访问宿主机网络
    2. 查看容器中的日志
    3. alpine镜像中jvm工具不可用问题
    4. docker启动java服务报错 Failed to start thread “GC Thread#0”
    5. java.lang.UnsatisfiedLinkError: no fontmanager in java.library.path
    6. 修改容器时区
      1. Dockerfile中指定时区
      2. 基于alpine的镜像中修改时区
    7. Mac中使用docker时遇到的问题
      1. mac中映射的文件需要先设置共享
      2. mac上宿主机和容器互相网络访问
      3. M1 Mac 上构建和运行 amd64/x86_64 架构镜像

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论