Docker实践学习笔记
1 PostgreSQL和插件的部署
需求:使用docker制作PostgreSQL的镜像并部署,同时需要为其安装postgis,pgrouting和timescaledb插件。
- 拉取基础镜像
postgis/postgis
,该镜像包含了postgres
和postgis
;
1
| docker pull postgis/postgis
|
- 编写
dockerfile
:这里以PostgresSQL 16
为例
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 postgis/postgis:latest
RUN sed -i 's|http://deb.debian.org/debian|http://mirrors.tencentyun.com/debian|g' /etc/apt/sources.list
RUN apt-get update && apt-get install wget
RUN wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | apt-key add -
RUN sh -c "echo 'deb https://packagecloud.io/timescale/timescaledb/ubuntu/ focal main' > /etc/apt/sources.list.d/timescaledb.list"
RUN apt-get update && \ apt-get install -y timescaledb-2-2.16.1-postgresql-16
RUN apt-get update && \ apt-get install -y postgresql-$PG_MAJOR-pgrouting
CMD ["postgres"]
|
说明:
1 2
| sed -i 's|http://deb.debian.org/debian|http://mirrors.tencentyun.com/debian|g' /etc/apt/sources.list
|
^7c1a05
-i
表示直接在原文件中进行修改,而不是将结果输出到标准输出。
's|old|new|g'
s
是 sed
的替换命令,表示将一个字符串替换成另一个字符串。
|
是定界符,通常用 /
作为定界符,但在这里使用了 |
,这在 URL 替换中很常见,因为 URL 中包含 /
,这样可以避免冲突。
g
代表全局替换,表示替换行内所有出现的匹配字符串。如果省略 g
,只会替换每行中第一个匹配的字符串。
- 最后一个参数是
sed
操作的文件
1
| sh -c "echo 'deb https://packagecloud.io/timescale/timescaledb/ubuntu/ focal main' > /etc/apt/sources.list.d/timescaledb.list"
|
^18d0f4
sh -c
是一个 shell 命令,用于执行字符串形式的命令。-c
表示后面跟随的内容是一条完整的命令,传递给 sh
来执行。
1
| wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | apt-key add -
|
这条命令用于下载 TimescaleDB 的 GPG 公钥并将其添加到系统的受信任密钥列表中,以便 APT 包管理器能够验证从 TimescaleDB 软件源下载的软件包的真实性和完整性。
wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey
:
wget
: 是一个用于从网络上下载文件的命令行工具。
--quiet
: 这个选项使 wget
以静默模式运行,不输出下载过程中的信息,仅输出错误和重要消息。
-O -
: 选项 -O
指定将下载的内容输出到某个文件,而不是默认的文件名。-
表示输出到标准输出(通常是终端)。
https://packagecloud.io/timescale/timescaledb/gpgkey
: 这是 TimescaleDB 的 GPG 公钥的 URL。wget
从这个地址下载公钥文件。
apt-key add -
:
apt-key
: 是一个 APT 包管理工具,用于管理 APT 的受信任密钥列表。
add
: 是 apt-key
的一个子命令,用于添加新的密钥到系统的受信任密钥列表中。
-
: 指定从标准输入(即管道)读取密钥数据。apt-key add -
将通过管道传递过来的 GPG 公钥添加到 APT 的受信任密钥列表中。
- 构建镜像:
1
| docker build -t postgres:tag .
|
- 创建数据卷,并运行容器:
1 2 3 4 5 6 7 8 9 10 11
| docker volume create pg_data
docker run -d \ --name postgres \ -e POSTGRES_USER=admin \ -e POSTGRES_PASSWORD=admin123 \ -e POSTGRES_DB=airport \ -e TZ=Asia/Shanghai \ -p 5432:5432 \ -v pg_data:/var/lib/postgresql/data \ postgres:tag
|
其中数据卷pg_data
保存postgresql的持久化数据。注意,如果使用目录挂载,数据库、用户和密码设置不会生效。
- 加载插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| docker exec -it postgres /bin/bash
echo "shared_preload_libraries = 'timescaledb'" >> /var/lib/postgresql/data/postgresql.conf
docker restart postgres
docker exec -it postgres /bin/bash
psql -U admin -d airport
create extension pgrouting; create extension timescaledb;
select extname from pg_extension;
|
2 多模块系统部署
描述:现在有一个多模块的系统,即父模块(只有pom管理依赖)下有多个子模块,程序的入口位于子模块admin
中。现在需要打成jar包,并使用docker部署在服务器中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>xxx</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> <finalName>xxxx</finalName> </build>
|
这里的finalName
为打包后jar包的名称。
- 在
admin
目录下执行下列命令,生成可执行jar
包admin.jar
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| FROM openjdk:8-jre
WORKDIR /app
ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY admin.jar /admin.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "admin.jar"]
|
- 将Dockerfile和jar包上传至服务器的文件夹中,例如
/usr/local/admin
1 2 3
| docker build -t admin:tag .
docker run -d --name admin -p 8080:8080 admin:tag
|
3 容器的日志
容器的日志,可以在容器中查看,也可以将日志文件的目录挂载到宿主机的目录上(或数据卷),直接在宿主机上查看。
假设logback
的配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="log.path" value="/usr/local/xxx/logs"/> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${log.pattern}</pattern> </encoder> </appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/sys_info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/sys_info.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>${log.pattern}</pattern> </encoder> </appender>
<root level="info"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root>
</configuration>
|
其中,日志文件的输出位置位于/usr/local/xxx/logs
。
- 如果
Dockerfile
没有另外设置WORKDIR
,则日志位于容器的上述目录,可进入容器中查看:
1 2 3 4 5 6 7 8 9
| docker exec -it <container_id> /bin/bash
cd /usr/local/xxx/logs
cat sys_info.log
|
如果设置了WORKDIR
,假设为app
,则:
1 2 3 4 5 6 7 8 9
| docker exec -it <container_id> /bin/bash
cd app/usr/local/xxx/logs
cat sys_info.log
|
1
| docker run -d --name xxxx -v /usr/local/xxx/logs:/usr/local/xxx/logs xxx:latest
|
则可以在宿主机中直接查看日志:
1 2 3
| cd /usr/local/xxx/logs
cat sys_info.log
|
同样的,如果设置了WORKDIR
,假设为app
,则:
1 2 3 4 5
| docker run -d --name xxxx -v /usr/local/xxx/logs:app/usr/local/xxx/logs xxx:latest
cd /usr/local/xxx/logs
cat sys_info.log
|
4 离线安装Docker
- 下载 Docker 安装包:从 Docker 官方网站下载适合 Docker 安装包(中科大镜像源)
一般来说,需要下载以下文件:
1 2 3 4
| containerd.io_<version>_<arch>.deb docker-ce_<version>_<arch>.deb docker-ce-cli_<version>_<arch>.deb docker-compose-plugin_<version>_<arch>.deb
|
其中arch
的查看方法详见:[[处理器架构#1 查看]]
1 2 3 4 5
| systemctl start docker
systemctl enable docker
systemctl status docker
|
- 从 Docker Compose 发布页面 下载 Docker Compose 二进制文件。
1
| cp docker-compose-<version> /usr/local/bin/docker-compose
|
1
| chmod +x /usr/local/bin/docker-compose
|
1
| docker-compose --version
|
在安装Docker的过程中,可能会出现错误:
1
| groupadd:无法打开 /etc/group
|
该错误的原因是因为对系统的关键文件进行了锁定,防止篡改,可以通过以下命令查看是否锁定:
如果显示:
1
| ----i---------- /etc/group
|
权限 i
表示该文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。
可执行下列执行暂时放开权限:
1 2
| chattr -i /etc/group chattr -i /etc/gshadow
|
安装完成后,可再执行以下命令恢复配置:
1 2
| chattr +i /etc/group chattr +i /etc/gshadow
|
5 应用更新
问题描述:Docker部署springboot应用时,怎么设置才能避免每次更新jar包时,需要重新构建镜像?
1 2 3 4 5 6 7 8 9
| FROM openjdk:8-jre
WORKDIR var/lib/app/
EXPOSE 8082
CMD ["java", "-jar", "var/lib/app/application.jar"]
|
构建镜像:
1
| docker build -t application .
|
- 使用
docker-compose
部署多个docker容器,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| services: sgis-postgis: image: postgres-timescale:15 container_name: postgis volumes: - "../postgres/data:/var/lib/postgresql/data/" ports: - "5432:5432" networks: - sgis_network restart: always
rabbitmq: image: rabbitmq:latest container_name: rabbitmq ports: - "5672:5672" - "15672:15672" volumes: - "../rabbitmq:/var/lib/rabbitmq" environment: - RABBITMQ_DEFAULT_USER: "fisher" - RABBITMQ_DEFAULT_PASS: "fisher" networks: - sgis_network restart: always
redis: image: redis:latest container_name: redis ports: - "6379:6379" networks: - sgis_network command: --save 60 1 --loglevel warning restart: always
tomcat: image: "tomcat:latest" container_name: tomcat privileged: true environment: - TZ="Asia/Shanghai" ports: - "9016:8080" networks: - sgis_network volumes: - "../tomcat/webapps:/usr/local/tomcat/webapps" restart: always
application: image: application:latest container_name: application ports: - "8082:8082" volumes: - "../app/application.jar:/var/lib/app/application.jar" networks: - sgis_network restart: always depends_on: - sgis-postgis - rabbitmq - redis networks: sgis_network: driver: bridge
|
其中../app/application.jar
为本地的jar文件存放位置,/var/lib/app/application.jar
为容器内jar的存放位置
使用命令启动多个容器:
当jar更新时,首先停止并删除原来的application
容器,然后替换原有的jar包,最后重启:
1 2 3 4
| docker rm -f application
|
著作権表示: 此文章版权归Kisugi Takumi所有,如有转载,请注明来自原作者