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 -version
,docker 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上搭建邮件服务器
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: