docker compose
配置文件分离
假设有如下配置文件,其中声明了两个容器,并且连接到同一网络:
services:
service1:
image: service1-image
networks:
- es-net
service2:
image: service2-image
networks:
- es-net
networks:
my-net:
driver: bridge由于容器都在一个配置中,使用 docker compose down 命令会停止所有容器,可以将容器、网络部分分离成 3 个配置文件,这样容器之间互不影响,也能共享一个网络。
# service1.yml
services:
service1:
image: service1-image
networks:
- es-net# service2.yml
services:
service2:
image: service2-image
networks:
- es-net# network.yml
networks:
my-net:
driver: bridge提示
若不单独提取网络配置,每个容器单独写一份相同的网络配置也能实现互通。
启动/停止容器
# 启动所有(先启动网络)
docker compose -f network.yml -f service1.yml -f service2.yml up -d
# 只启动一个容器 (先停止容器)
docker compose -f service1.yml -f network.yml up -ddocker compose -f service1.yml -f service2.yml -f network.yml down常用软件安装
mysql
准备目录
mkdir -p /usr/local/docker/mysql
cd /usr/local/docker/mysql
mkidr ./data ./log ./conf
vim docker-compose.ymldocker-compose.yml 参考地址
services:
# 当前节点的mysql为服务名,可根据情况随意命名
mysql:
image: mysql:5.7.43
# restart: always
container_name: mysqldb5.7.43
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: root
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
# 允许来自任何 IP 地址的远程连接
--bind-address=0.0.0.0
ports:
- 3306:3306
volumes:
- /usr/local/docker/mysql/data:/var/lib/mysql
- /usr/local/docker/mysql/log:/var/log/mysqlservices:
mysql:
image: mysql:8.0.34
restart: always
container_name: mysqldb8.0.34
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: your_user
MYSQL_PASSWORD: your_password
MYSQL_DATABASE: your_database
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
# 此处可设置服务端接收的最大sql文件
--max_allowed_packet=128M
# 允许来自任何 IP 地址的远程连接
--bind-address=0.0.0.0
ports:
- 3306:3306
volumes:
- /usr/local/docker/mysql/data:/var/lib/mysql
- /usr/local/docker/mysql/log:/var/log/mysql
# 注意,当指定了外部配置文件与外部存储路径时,也需要指定 /var/lib/mysql-files的外部目录,否则会报错
- /usr/local/docker/mysql/mysql-files:/var/lib/mysql-filesservices:
mysql:
image: mysql:8.1.0
restart: always
container_name: mysqldb8.1.0
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: root
command: --default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
--bind-address=0.0.0.0
ports:
- 3306:3306
volumes:
- /usr/local/docker/mysql/data:/var/lib/mysql
- /usr/local/docker/mysql/log:/var/log/mysql挂载配置文件:
# 拷贝配置文件到宿主机
docker cp 容器ID:/etc/mysql/. /usr/local/docker/mysql/conf
# 编辑 docker-compose.yml 文件,在挂载目录中添加如下配置:
# - /usr/local/docker/mysql/conf:/etc/mysql
# 重启容器
docker compose down
docker compose up -dOracle
Oracle 19c 为长期支持版,详情参考 Oracle 章节。
services:
oracle19c:
image: registry.cn-hangzhou.aliyuncs.com/zhuyijun/oracle:19c
container_name: oracle19c
# 赋予容器更高权限
privileged: true
restart: always
ports:
- "1521:1521"
environment:
TZ: Asia/Shanghai
# 数据库实例唯一标识符
ORACLE_SID: orcl
# 可插拔数据库名,相当于一个独立的数据库;可以创建多个PDB,他们之间完全独立
ORACLE_PDB: orclpdb
# 设置SYS(SYS拥有最高权限)、STSTEM(普通管理员)用户密码
ORACLE_PWD: root
# 数据库的版本(standard 标准版,enterprise 企业版)
ORACLE_EDITION: standard
ORACLE_CHARACTERSET: AL32UTF8
volumes:
- ./data:/opt/oracle/oradata
- /etc/localtime:/etc/localtime测试是否可用
# 通常连接PDB,它在多租户情况下更灵活(不同租户可创建并连接到不同的PDB,彼此相互隔离)
# SID 在单租户比较常用
# 为啥必须加 as sysdba 呢,因为 sys 用户比较牛逼,不加不让连接
sqlplus sys/root@localhost:1521/orcl as sysdba
sqlplus sys/root@localhost:1521/orclpdb as sysdba
# 查看当前连接是SID 还是 PDB ( 仅在sqlplus中可用 )
SHOW CON_NAME;达梦数据库
docker-compose.yml 参考地址
安装镜像
在达梦官网下载 Docker 镜像文件,并加载到服务器
# 加载静态镜像 docker load -i dm8_xxx.tar # 镜像加载后,可以重命名一下,以免名字太长不美观 docker tag 镜像ID dm8:my_test_version启动容器
services: dm8_test: image: dm8:my_test_version container_name: dm8_test restart: always privileged: true ports: - "5236:5236" environment: - LD_LIBRARY_PATH=/opt/dmdbms/bin - PAGE_SIZE=16 - EXTENT_SIZE=32 # 1:大小写敏感;0:大小写不敏感,默认值:1 # 大小写敏感时,小写的标识符应用""括起,否则被系统自动转换为大写 - CASE_SENSITIVE=1 - LOG_SIZE=1024 # 字符集选项;0:GB18030;1:UTF-8;2:EUC-KR,默认值:0 - UNICODE_FLAG=1 # 初始化数据库实例名字,默认值:DAMENG - INSTANCE_NAME=DAMENG # 初始化实例时设置 SYSDBA 用户的密码(长度为 8~48 个字符,需包含大小写字母和数字,docker版暂不支持特殊字符) - SYSDBA_PWD=Test123456 volumes: # 无需提前创建 data 目录 - ./data:/opt/dmdbms/data基本操作
创建用户和表空间# 1. 连接数据库。disql 是达梦数据库的命令行工具 # 格式为:disql SYSDBA/密码@服务器地址:端口号 cd /opt/dmdbms/bin ./disql SYSDBA/密码 ./disql SYSDBA/密码@127.0.0.1:5236 @/path/to/script.sql # 执行sql脚本 # 2. 新建表空间。初始大小为 128M,每次自动扩展 256M ,扩展上限 60000M CREATE TABLESPACE "TEST_TBS" DATAFILE '/opt/dmdbms/data/DAMENG/TEST_TBS.DBF' SIZE 128 AUTOEXTEND ON NEXT 256 MAXSIZE 60000 CACHE = NORMAL; # 3. 创建用户关联表空间。新建用户TEST_USER并为其指定默认表空间为 TEST_TBS,索引表空间为 TEST_TBS CREATE USER "TEST_USER" IDENTIFIED BY "pass123" DEFAULT TABLESPACE "TEST_TBS" DEFAULT INDEX TABLESPACE "TEST_TBS"; # 4. 授予用户 DBA 权限 # 权限说明参考:https://eco.dameng.com/document/dm/zh-cn/pm/discretionary-access-control.html GRANT "DBA" TO "TEST_USER" WITH ADMIN OPTION; GRANT "RESOURCE" TO "TEST_USER" WITH ADMIN OPTION; # 5. 新建模式 schema 绑定到用户(类似于MySQL的数据库) CREATE SCHEMA "my_test_schema" AUTHORIZATION "TEST_USER"; CALL SP_SET_SCHEMA_DESC('my_test_schema', '模式备注'); # 给模式添加备注信息 # 6. 创建user表 CREATE TABLE "my_test_schema"."user" ...导出导出# !!! 注意,导入导出需保证目标机器和源机器达梦数据库版本保持一致! # 推荐使用 Sqlark 工具导入导出,非常方便。(如果本地安装了达梦,他会使用本地的dimp指令远程导入到目标机器,不存在编码问题) # 参考地址:https://eco.dameng.com/document/dm/zh-cn/pm/dexp-dimp-function-introduction.html # 注意,导入成功的前提是两个数据库实例的初始化参数需保持一致(如大小写敏感、字符集编码等),若存在不一致现象,最好的方式是在目标机器上新建一个和源数据库例初始化参数保持一致的数据库实例。 # dexp 和 dimp 是 DM 数据库自带的导出导出工具,可以在安装目录 /dmdbms/bin 中找到 cd /opt/dmdbms/bin # 指定schema导出。文件名为 db_str.dmp,导出的日志文件名为 db_str.log,导出文件的路径为/home ./dexp USERID=SYSDBA/password@127.0.0.1:5236 FILE=db_str.dmp DIRECTORY=/home LOG=db_str_out.log SCHEMAS="xxx" # 指定schema导入。这种方式导入,目标schema名称和源schema名称一致。 ./dimp USERID=SYSDBA/password@127.0.0.1:5236 FILE=db_str.dmp DIRECTORY=/home LOG=db_str_in.log SCHEMAS="xxx" # 指定schema导入。将源库中名为SOURCE的模式(schema)导入到目标库中TARGET模式中。无需关注源模式和目标模式所属用户,他们不会冲突。 ./dimp USERID=SYSDBA/password@127.0.0.1:5236 FILE=db_str.dmp DIRECTORY=/home LOG=db_str_in.log REMAP_SCHEMA="SOURCE:TARGET" # 指定用户导出。包括用户关联的包括模式、表、数据等(表空间是物理结构,不会被导出)。他和指定schema导出的区别是:指定schema导出是指定用户导出的一个子集。 # TABLESPACE=Y表示导出表空间名称,加入此项配置,在后续导入前需手动创建表空间。 ./dexp USERID=SYSDBA/password@127.0.0.1:5236 FILE=db_str.dmp DIRECTORY=/home LOG=db_str_out.log OWNER="xxx" TABLESPACE=Y # 指定用户导入。CTRL_INFO=1表示导入表空间定义,需在导入前手动创建一个和源库相同的表空间。 ./dimp USERID=SYSDBA/password@127.0.0.1:5236 FILE=db_str.dmp DIRECTORY=/home LOG=db_str_in.log OWNER="xxx" CTRL_INFO=1JSON 对象查询-- 1. 建表 -- CREATE TABLE my_table ( -- id INT, -- json_data CLOB -- ); -- 2. 测试数据 -- { -- "name": "张三", -- "age": 30, -- "address": { -- "city": "北京", -- } -- } -- 3. 查询 SELECT id, JSON_VALUE(json_data, '$.address.city') AS city FROM my_table WHERE JSON_VALUE(json_data, '$.address.city') = '北京';JSON 数组查询-- 1. 建表 -- CREATE TABLE my_table ( -- id INT, -- json_data CLOB -- ); -- 2. 测试数据 -- [ -- { "name": "张三", "age": 30 }, -- { "name": "李四", "age": 25 }, -- { "name": "王五", "age": 35 } -- ] -- 3. 分页查询 (子查询用于数据过滤,外部用于分页) SELECT t.name, t.age, t.row_num FROM ( SELECT jt.name, jt.age, -- 行号不受数值影响,即使年龄相同,行号也不一样 -- 行号在本级查询中不能被读取,需在外层获取 ROW_NUMBER() OVER (ORDER BY jt.age) AS row_num FROM my_table, JSON_TABLE(json_data, '$[*]' -- '$[*]' 表示数组中的每个元素 COLUMNS ( -- COLUMNS 子句用来定义每个数组元素的字段 name VARCHAR(50) PATH '$.name', age INT PATH '$.age' ) ) AS jt WHERE jt.age > 30 ) AS t -- 注意下面的分页参数需要自行赋值,如下写法只是示例 WHERE t.row_num BETWEEN (${page_number} - 1) * ${page_size} + 1 AND ${page_number} * ${page_size};整合 Java
pom.xml<properties> <dm.version>8.1.3.140</dm.version> </properties> <!-- https://mvnrepository.com/artifact/com.dameng/DmJdbcDriver18 --> <dependency> <groupId>com.dameng</groupId> <artifactId>DmJdbcDriver18</artifactId> <version>${dm.version}</version> </dependency>application.ymlspring: datasource: url: jdbc:dm://172.16.1.120:5236/schema_name username: xxx password: xxx # driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: dm.jdbc.driver.DmDriver type: com.alibaba.druid.pool.DruidDataSource
Redis
docker-compose.yml 参考地址
services:
redis:
image: redis:7.2
restart: always
container_name: redis
ports:
- 6379:6379
command: redis-server --port 6379 --requirepass "day-day-hard-work"GitLab
代码托管平台,默认管理员账号为 root,密码通过客户端设置;
为便于学习,建议设置密码为 12345678
docker-compose.yml 参考地址
services:
gitlab:
image: "gitlab/gitlab-ce:17.5.4-ce.0"
restart: unless-stopped
# 当前安装 gitlab 服务器地址
hostname: "192.168.2.103"
environment:
TZ: "Asia/Shanghai"
GITLAB_OMNIBUS_CONFIG:
# external_url用于设置访问gitlab的地址,可以是域名;默认容器内暴露端口是80,若指定其他端口,需额外配置nginx['listen_port']
# gitlab_shell_ssh_port用于设置克隆仓库时,web端显示的ssh端口,默认22;修改后需注意暴露端口
|
external_url 'http://192.168.2.103:8080'
nginx['listen_port'] = 8080
gitlab_rails['gitlab_shell_ssh_port'] = 2222
gitlab_rails['time_zone'] = 'Asia/Shanghai'
ports:
- "8080:8080"
- "8443:443"
- "2222:22"
volumes:
- /usr/local/docker/gitlab/config:/etc/gitlab
- /usr/local/docker/gitlab/data:/var/opt/gitlab
- /usr/local/docker/gitlab/logs:/var/log/gitlab提示
GitLab 占用内存较大,估计会消耗 2G 内存
Nexus
Nexus 是一个仓库管理器,用于存储和管理软件组件和依赖项。它被广泛用于构建和部署应用程序时,用于管理各种软件资产,包括但不限于 Java JAR 文件、Maven 构件、Docker 镜像、npm 包、RubyGems 等。
安装
maven 私服平台,更早的版本默认的管理员用户名和密码是 admin/admin123,现在 admin 用户的初始密码需在/nexus-data/admin.password中查看
为便于学习,登陆后密码修改为 12345678
注意宿主机数据卷 data 目录需有读写权限 chmd 777 /dada
docker-compose.yml 参考地址
services:
nexus:
restart: always
image: sonatype/nexus3:3.61.0
container_name: nexus
environment:
TZ: Asia/Shanghai
# Xms 初始堆大小
# Xmx 最大堆空间
# XX:MaxDirectMemorySize 元数据区大小,若不指定,会无上限耗用系统内存
- INSTALL4J_ADD_VM_PARAMS=-Xms2703m -Xmx2703m -XX:MaxDirectMemorySize=2703m
# Nexus Context Path,url路径前缀,默认为/
- NEXUS_CONTEXT=nexus
ports:
- 8081:8081
volumes:
- /usr/local/docker/nexus/data:/nexus-data提示
Nexus 占用内存较大,估计会消耗 2G 内存
仓库描述
Nexus 常用的仓库为 public、releases 和 snapshot;默认的,public 仓库包含 releases 和 snapshot 仓库以及中央仓库
使用
<!-- maven 的 setting.xml 配置 -->
<servers>
<!-- 设置仓库账号密码 -->
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>12345678</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>12345678</password>
</server>
</servers>
<!-- 项目中 pom.xml 配置 -->
<distributionManagement>
<!--配置上传地址-->
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.2.103:8081/nexus/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.2.103:8081/nexus/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement><!-- maven 的 setting.xml 配置 -->
<mirrors>
<mirror>
<id>my-nexus-proxy</id>
<url>http://192.168.2.103:8081/nexus/repository/maven-public/</url>
<!-- mirrorOf指定了要代理的存储库,*代表所有 -->
<mirrorOf>central,releases</mirrorOf>
</mirror>
</mirrors>
<!-- 项目中 pom.xml 配置 -->
<repositories>
<!--下载地址,配置后优先从私服下载,若不存在再走官服-->
<repository>
<id>my-nexus-proxy</id>
<url>http://192.168.2.103:8081/nexus/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>my-nexus-proxy</id>
<url>http://192.168.2.103:8081/nexus/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>提示
- setting.xml 中的 id 必须与 pom.xml 中的 id 名称保持一致
- 项目版本号有
SNAPSHOT标识的,会发布到 Snapshot Repository,否则发布到 Release Repository - 打开 idea 的总是更新快照,刷新依赖就能下载最新快照版本 File->Settings->Build->Bulid Tools->Maven->勾选 Always update snapshot
测试推送依赖
# 1. 打包本地代码并推送
mvn deploy
# 2. 推送jar文件到仓库
mvn deploy:deploy-file \
-Durl=http://192.168.2.103:8081/nexus/repository/maven-snapshots/ \
-DrepositoryId=nexus-snapshots \
-DgroupId=com.zjx.test \
-DartifactId=test \
-Dversion=1.0 \
-Dpackaging=jar \
-Dfile=D:\test\test-1.0.jarregistry
一个用于存储和管理 Docker 镜像的开源仓库服务,docker 官方镜像仓库。它允许开发人员构建、存储和共享 Docker 镜像,这些镜像用于容器化应用程序。
docker-compose.yml 参考地址
提示
若仓库需要加密访问,先完善仓库加密部分
services:
registry:
image: registry:2.8.3
container_name: docker-registry
restart: always
ports:
- 5000:5000
environment:
TZ: Asia/Shanghai
# 配置镜像存储目录
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
# 账号密码【可选配置】
REGISTRY_AUTH: htpasswd # 身份验证类型
# 指定密码文件的路径,注意htpasswd是文件名不是目录
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
# 用户尝试访问 Registry 时显示一个提示
REGISTRY_AUTH_HTPASSWD_REALM: Good Job
volumes:
- /usr/local/docker/registry/data:/var/lib/registry
# 账号密码【可选配置】
- /usr/local/docker/registry/conf/config.yml:/etc/docker/registry/config.yml
- /usr/local/docker/registry/auth:/auth
# registry 的 webui 工具
registry-frontend:
image: konradkleine/docker-registry-frontend:v2
ports:
- "8082:80"
environment:
# REGISTRY_HOST也可以使用 "registry"
ENV_DOCKER_REGISTRY_HOST: 192.168.2.103
ENV_DOCKER_REGISTRY_PORT: 5000
restart: unless-stopped在/usr/local/docker/registry 新建 config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
#配置删除权限,默认安装的Registry不支持删除
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3仓库加密
# 账号密码登录
apt-get install apache2-utils
cd /usr/local/docker/registry/auth
# 输入如下指令设置用户名,根据提示设置密码(便于学习,密码12345678)
htpasswd -Bbn root 12345678 > ./htpasswd # -B使用bcrypt加密;-b使用单行命令设置密码;-n在标准输出上显示结果
# 若是想添加其他账户,使用如下指令
htpasswd -Bb ./htpasswd username newpassword在 docker 客户端 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件,此配置 Ubuntu 和 CentOS 通用)
// registry-mirrors 加速器,可登录自己的阿里云查看
// insecure-registries 用于指定未使用https或使用了自签名证书的仓库
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.2.103:5000"]
}sudo systemctl daemon-reload
sudo systemctl restart docker测试上传镜像
docker login 192.168.2.103:5000
docker pull nginx
# 标记本地镜像并指向目标仓库
docker tag nginx 192.168.2.103:5000/nginx
docker push 192.168.2.103:5000/nginx由于 registry 只提供了 api,docker-registry-frontend根据其 api 实现了 web ui,可更加方便管理镜像;docker-registry 的 webui 工具还可以使用 docker-registry-ui、docker-registry-web 等,用法都差不多,不再讨论
浏览器访问 http://192.168.2.103:5000/v2/,响应为{}说明 registry 安装成功;浏览器访问 http://192.168.2.103:8082/ 即可在 web ui 中管理镜像
Harbor
Harbor 可作为 registry 的替代方案,其提供更全面功能包括身份验证、访问控制、镜像扫描复制、漏洞管理、加密传输等等
Nginx
docker-compose.yml 参考地址
services:
nginx:
image: nginx
restart: unless-stopped
environment:
TZ: Asia/Shanghai
NGINX_PORT: 80
command: [nginx-debug, "-g", "daemon off;"]
ports:
- "80:80"
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html说明:当使用 daemon off 时,它告诉 Nginx 在启动时以非守护进程方式运行,相当于在 Docker 容器中运行 Nginx 并能够看到日志信息,便于进行故障排查。然而,正式生产环境下,不应该有此项设置,这样可以更好地管理服务并确保稳定性。
提示
数据卷无法自动创建文件(它只会创建目录)
创建 nginx.conf 文件,并写入如下配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name 127.0.0.1;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}Jenkins
docker-compose.yml 参考地址
services:
jenkins:
# lts为长期支持版
image: jenkins/jenkins:2.426.2-lts-jdk17
# 故障时重启
restart: on-failure
environment:
TZ: Asia/Shanghai
JENKINS_JAVA_OPTS: "-Dhudson.footerURL=http://victor.spring-cloud.cn/"
# 8080为web端口,50000为集群端口
ports:
- "8083:8080"
- "50000:50000"
volumes:
- ./jenkins_home:/var/jenkins_home修改文件权限
# 递归为当前文件夹添加权限
chmod -R 777 /usr/local/docker/jenkins/jenkins_home查看初始密码
# 通过日志查看初始密码
docker logs container_id
# 也可进入容器查看密码
docker exec -it container_id bash
cat /var/jenkins_home/secrets/initialAdminPassword提示
使用初始密码登录成功后,会添加账号,为便于学习,账号密码:root 12345678
安装插件
- Publish Over SSH -- 用于连接其他计算机实现远程部署。
- Dashboard View -- 可定制的仪表板,呈现各种视图。
- Maven Integration -- 可以在新建任务时可选择构建 maven 项目。
- GitLab -- 可为 pipeline 提供 webhook 以供 gitlab 触发。
- Generic Webhook Trigger -- 多分支流水线中能帮助我们触发某个分支的构建执行。
- Folder -- 像管理文件夹下的文件一样来管理 Jenkins 项目,并简化了 pipeline 间的相互引用(貌似默认安装了)。
- Conditional BuildStep -- 优雅的判断逻辑语法
ES & Kibana
安装单节点 ES 和 Kibana 示例:
docker-compose.yml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
privileged: true
networks:
- es-net
environment:
- TZ=Asia/Shanghai
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- ELASTICSEARCH_USERNAME=your_username
- ELASTIC_PASSWORD=your_elastic_password
# 注意,若开启安全策略,用户名只能手动配置(通过命令行),ELASTICSEARCH_USERNAME 配置将失效(建议生产开启)
- xpack.security.enabled=false
- xpack.security.transport.ssl.enabled=false
ports:
- "9200:9200"
- "9300:9300"
volumes:
- ./es/es-data:/usr/share/elasticsearch/data
- ./es/es-plugins:/usr/share/elasticsearch/plugins
kibana:
image: docker.elastic.co/kibana/kibana:8.17.0
environment:
- TZ=Asia/Shanghai
- ELASTICSEARCH_URL=http://elasticsearch:9200
# 注意,较新版本的 kibana 不允许指定用户名为 elastic(因为他是ES默认的管理员用户名)
- ELASTICSEARCH_USERNAME=your_username
- ELASTICSEARCH_PASSWORD=your_elastic_password
ports:
- "5601:5601"
depends_on:
- elasticsearch
networks:
- es-net
networks:
es-net:
driver: bridge设置文件权限
# 创建挂载目录(注意 kibana 未在 yml 中声明,下文汉化才会用到,先创建目录) mkdir -p ./es/es-data ./es/es-plugins ./kibana # 为保证es能将挂载文件写入宿主机,需要修改文件夹的读写权限 chmod -R a+rw ./esES 安装中文分词器
analysis-ik安装非常简单,注意分词器的版本必须和 ES 一致,相差一个小版本都不行!下载并将压缩包放到 ES 的插件文件夹中,解压后重启 ES 即可。
解压安装# 将二进制包上传到宿主机中,并解压 # 注意不能直接解压到 es-plugins 目录下,需创建一个父级目录 mkdir -p ./es/es-plugins/analysis-ik unzip elasticsearch-analysis-ik-8.17.0.zip -d ./es/es-plugins/analysis-ik chmod -R a+rw ./es命令行安装# 进入 ES 容器中,使用 ES 插件安装工具运行如下指令(注意版本号需和 ES 一致) # 推荐使用二进制压缩包安装,指令安装可能会非常慢 bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/8.17.0Kibana 汉化
先让 Kibana 启动,然后将配置文件复制到宿主机,再配置文件中追加一行配置,添加 kinbana 数据卷,重启容器即可。
追加配置# 拷贝 kibana 配置文件 docker cp 容器id:/usr/share/kibana/config/kibana.yml ./kibana # 在配置文件末尾追加 中文配置 echo 'i18n.locale: "zh-CN"' >> ./kibana/kibana.yml chmod -R a+rw ./kibana修改 ymlservices: kibana: image: docker.elastic.co/kibana/kibana:8.17.0 ... volumes: ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
大数据
ClickHouse
docker-compose.yml 参考地址
services:
clickhouse:
image: clickhouse/clickhouse-server:24.8.5.115
container_name: clickhouse
restart: unless-stopped
# 8123 是http端口;9000是TCP端口;他们都是客户端端口,只是协议不同,TCP 更快
ports:
- "8123:8123"
- "9000:9000"
volumes:
- ./data/lib:/var/lib/clickhouse/
- ./data/log:/var/log/clickhouse-server/
# 启动容器时创建一个用户和数据库
# 默认访问管理 0 关闭,1 开启;开启会使用RBAC(基于角色的访问控制),生产环境适用
environment:
- TZ=Asia/Shanghai
- CLICKHOUSE_DB=my_database
- CLICKHOUSE_USER=username
- CLICKHOUSE_PASSWORD=password
- CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=0
# 修改文件句柄和最大进程数
ulimits:
nproc: 65535
nofile:
soft: 262144
hard: 262144
# 提升容器的权限
cap_add:
- SYS_NICE
- NET_ADMIN启动容器后,先验证 ClickHouse 是否运行成功,再将默认配置文件拷贝到宿主机中:
# 验证是否运行成功
docker exec -it clickhouse bash;
clickhouse-client --host 127.0.0.1 --port 9000 --user <用户名> --password <密码> --database <数据库名>;
sql> show tables;
# 拷贝默认配置到宿主机
docker cp clickhouse:/etc/clickhouse-server ./data/config;修改 docker-compose.yml,添加数据卷,主要配置如下:
services:
clickhouse:
volumes:
- ./data/config:/etc/clickhouse-server/修改后重启容器,即可完成配置文件的双向绑定。
kafaka
在 Kafka 中,可以为节点设置两个不同的角色(Broker 和 Controller),Broker 可理解为实际读写消息的节点,Controller 负责处理元数据的读写请求、执行领导选举、检测失败节点(高可用核心)。同一节点可以同时作为 Broker 和 Controller,也可分开单独部署。
Kafka 4.0 + KRaft + Kafka UI + Volume 安装 kafka 模拟集群示例(Kafka 客户端工具有很多,这里以 Kafka UI 为例):
9092 为 Kafka 客户端访问默认端口,9093 为 KRaft Controller 选举默认端口;
services:
kafka0:
image: apache/kafka:4.0.0
container_name: kafka0
restart: unless-stopped
ports:
- "9092:9092"
volumes:
# Kafka KRaft 模式(无 ZooKeeper):集群元数据和消息数据都存储在此目录中
# 注意:这里虽然叫 logs,但它是 Kafka 的数据目录(包含消息文件和元数据日志),不是运行时日志文件
- ./data/kafka0-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
# 集群中每个节点的唯一 ID
KAFKA_NODE_ID: 1
# 节点角色:
# broker:仅处理客户端读写请求
# controller:仅管理集群元数据、选举控制器
# 可以单独设置或同时存在
KAFKA_PROCESS_ROLES: broker,controller
# Broker 间通信使用的监听器名称
KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
# 控制器节点间通信的监听器名称
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
# 定义监听器与安全协议的映射关系,PLAINTEXT 是明文协议(协议类型包含明文、加密、SASL、SSL 等)
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT
# 监听地址与端口:
# CLIENT 用于客户端访问
# CONTROLLER 用于控制器节点间通信(内部使用,不对外暴露)
KAFKA_LISTENERS: CLIENT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
# 广播地址:告诉其他节点和客户端如何访问当前 Broker,IP 为当前机器 IP 地址
# 不要写成 CLIENT://kafka0:9092,因为对于客户端而言,无法通过 服务名+端口 访问
KAFKA_ADVERTISED_LISTENERS: CLIENT://198.168.0.2:9092
# Controller 选举参与者列表(仅包含具有 controller 角色的节点)
# 只在容器内部通信,不对宿主机暴露,不会与其他容器的 9093 端口冲突,可写成 服务名+端口 的形式
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka0:9093,2@kafka1:9093,3@kafka2:9093
# 生产环境建议关闭自动创建主题
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
# 控制日志刷盘频率:每接收 10000 条消息强制刷盘一次
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
# 集群 ID(KRaft 模式固定且唯一,集群第一次启动需统一)
KAFKA_CLUSTER_ID: kraft-cluster-123456
networks:
- kraft-net
kafka1:
image: apache/kafka:4.0.0
container_name: kafka1
restart: unless-stopped
ports:
- "9094:9094"
volumes:
- ./data/kafka1-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_LISTENERS: CLIENT://0.0.0.0:9094,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: CLIENT://198.168.0.2:9094
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka0:9093,2@kafka1:9093,3@kafka2:9093
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
KAFKA_CLUSTER_ID: kraft-cluster-123456
depends_on:
- kafka0
networks:
- kraft-net
kafka2:
image: apache/kafka:4.0.0
container_name: kafka2
restart: unless-stopped
ports:
- "9095:9095"
volumes:
- ./data/kafka2-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_LISTENERS: CLIENT://0.0.0.0:9095,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: CLIENT://198.168.0.2:9095
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka0:9093,2@kafka1:9093,3@kafka2:9093
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
KAFKA_CLUSTER_ID: kraft-cluster-123456
depends_on:
- kafka0
networks:
- kraft-net
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
restart: unless-stopped
ports:
- "8080:8080"
environment:
- TZ=Asia/Shanghai
# Kafka UI 集群配置(Kafka UI 支持多个集群配置,以下为第一个集群)
# 支持用 KAFKA_CLUSTERS_n_ 这种前缀来配置多个集群,n 从 0 开始递增
- KAFKA_CLUSTERS_0_NAME=kraft-cluster
# 连接所有 Broker,避免单点故障导致 UI 无法访问
- KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS=kafka0:9092,kafka1:9094,kafka2:9095
depends_on:
- kafka0
- kafka1
- kafka2
networks:
- kraft-net
networks:
kraft-net:
driver: bridgeservices:
kafka-controller:
image: apache/kafka:4.0.0
container_name: kafka-controller
restart: on-failure
ports:
- "9094:9094"
volumes:
- ./data/kafka-controller-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT
KAFKA_LISTENERS: CONTROLLER://0.0.0.0:9094
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-controller:9094,2@kafka1:9093,3@kafka2:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
KAFKA_CLUSTER_ID: kraft-cluster-123456
networks:
- kraft-net
kafka1:
image: apache/kafka:4.0.0
container_name: kafka1
restart: unless-stopped
ports:
- "9092:9092"
volumes:
- ./data/kafka1-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
KAFKA_LISTENER_NAME_CLIENT_SECURITY_PROTOCOL: PLAINTEXT
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_LISTENERS: CLIENT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: CLIENT://kafka1:9092
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-controller:9094,2@kafka1:9093,3@kafka2:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
KAFKA_CLUSTER_ID: kraft-cluster-123456
depends_on:
- kafka-controller
networks:
- kraft-net
kafka2:
image: apache/kafka:4.0.0
container_name: kafka2
restart: unless-stopped
ports:
- "9095:9095"
volumes:
- ./data/kafka2-data:/kafka/kraft-combined-logs
environment:
TZ: Asia/Shanghai
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
KAFKA_LISTENER_NAME_CLIENT_SECURITY_PROTOCOL: PLAINTEXT
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_LISTENERS: CLIENT://0.0.0.0:9095,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: CLIENT://kafka2:9095
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-controller:9094,2@kafka1:9093,3@kafka2:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
KAFKA_LOG_FLUSH_INTERVAL_MESSAGES: 10000
KAFKA_CLUSTER_ID: kraft-cluster-123456
depends_on:
- kafka-controller
networks:
- kraft-net
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
restart: unless-stopped
ports:
- "8080:8080"
environment:
- TZ=Asia/Shanghai
- KAFKA_CLUSTERS_0_NAME=kraft-cluster
- KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS=kafka1:9092,kafka2:9095
depends_on:
- kafka1
- kafka2
networks:
- kraft-net
networks:
kraft-net:
driver: bridge启动成功后,访问 localhost:8080 可打开Kafka UI
localhost:9092、localhost:9094、localhost:9095 访问 Kafka Broker

