云服务器部署可视化Docker私有仓库(Ubuntu)

云服务器部署可视化Docker私有仓库(Ubuntu)

这里测试的机器为ubuntu22.04

一、环境安装

docker安装就不赘述了
先升级,再从官方仓库安装docker compose

language-bash
1
2
3
apt update
apt upgrade
apt install docker-compose

二、部署私有仓库UI

Docker提供了一个叫registry的镜像,给大家搭建私有仓库,但是没有可视化界面。
https://hub.docker.com/r/joxit/docker-registry-ui
这个镜像在registry基础之上,开发了网页可视化。

1. 创建一个文件夹Docker_Registry

2. 进入其中继续创建registry-data文件夹和docker-compose.yaml文件

3. yaml文件

language-yaml
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
version: '3.8'

services:
registry-ui:
image: joxit/docker-registry-ui:main
restart: always
ports:
- 8090:80 #这里8090改成可视化网页服务端口
environment:
- SINGLE_REGISTRY=true
- REGISTRY_TITLE=Xiamu Docker Registry UI #这里可以修改标题
- DELETE_IMAGES=true
- SHOW_CONTENT_DIGEST=true
- NGINX_PROXY_PASS_URL=http://registry-server:5000
- SHOW_CATALOG_NB_TAGS=true
- CATALOG_MIN_BRANCHES=1
- CATALOG_MAX_BRANCHES=1
- TAGLIST_PAGE_SIZE=100
- REGISTRY_SECURED=false
- CATALOG_ELEMENTS_LIMIT=1000
container_name: registry-ui
depends_on:
- registry-server

registry-server:
image: registry:2.8.2
restart: always
environment:
REGISTRY_HTTP_HEADERS_Access-Control-Origin: '[http://your_server_ip]' # 这里改成你的云服务ip,启用CORS
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
REGISTRY_HTTP_HEADERS_Access-Control-Credentials: '[true]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
volumes:
- ./registry-data:/var/lib/registry
container_name: registry-server

4. 部署

进入Docker_Registry目录,执行

language-bash
1
docker-compose -f ./docker-compose.yaml up

三、访问

通过http://your_server_ip:8090 访问UI

四、上传和拉取镜像

打开vi /etc/docker/daemon.json添加以下内容:

language-txt
1
"insecure-registries":["http://your_server_ip:8090"]

这样docker才会信任你的私有仓库。

假设你的服务器ip为192.168.750.101,port为8090
推送镜像到私有镜像服务必须先tag,步骤如下:

  1. 重新tag本地镜像,名称前缀为私有仓库的地址: 192.168.150.101:8090/
language-dart
1
docker tag nginx:latest 192.168.150.101:8090/nginx:1.0
  1. 推送镜像
language-dart
1
docker push 192.168.150.101:8090/nginx:1.0
  1. 拉取镜像
language-dart
1
docker pull 192.168.150.101:8090/nginx:1.0
Docker Compose怎么保证其他服务在Nacos完全启动后再启动

Docker Compose怎么保证其他服务在Nacos完全启动后再启动

首先,docker compose有一个关键字depends_on是可以一定程度解决services之间的依赖问题,但是depends_on仅仅只是指定了services的启动顺序,并不能保证,前置service完全启动后,后置service才启动。

此时,需要另一个关键字叫healthcheck

样例

nacos版本为v2.3.0

language-yaml
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
  mysql_nacos:
container_name: mysql_nacos
build:
context: .
dockerfile: ./image/mysql/5.7/Dockerfile
image: example/mysql:5.7
env_file:
- ../env/mysql.env
volumes:
- ./mysql:/var/lib/mysql
# ports:
# - "3307:3306"
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}" ]
interval: 10s
timeout: 10s
retries: 10

nacos1:
hostname: nacos1
container_name: nacos1
image: nacos/nacos-server:${
NACOS_VERSION}
volumes:
- ./cluster-logs/nacos1:/home/nacos/logs
# ports:
# - "7848:7848"
# - "8845:8848"
# - "9868:9848"
# - "9850:9849"
env_file:
- ../env/nacos-hostname.env
# restart: always
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]
interval: 10s
timeout: 10s
retries: 10
depends_on:
mysql_nacos:
condition: service_healthy

nginx_nacos:
hostname: nginx_nacos
image: nginx:stable
container_name: nginx_nacos
volumes:
- ../nginx_nacos/nginx.conf:/etc/nginx/nginx.conf
- ../nginx_nacos/conf.d/default.conf:/etc/nginx/conf.d/default.conf
- ../nginx_nacos/logs:/var/log/nginx
- ../nginx_nacos/html:/usr/share/nginx/html
ports:
- "80:80"
depends_on:
nacos1:
condition: service_healthy

这是一个双层依赖,nginx_nacos依赖于nacos1,同时nacos1依赖于mysql_nacos

mysql_nacos基于 healthcheck:test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}" ]来确认自己的健康状态,只有当test内容执行成功并返回状态码0,才会认为此service已完全执行成功。

同理nacos服务是基于healthcheck:test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]来判断健康状态的。

Docker部署Nacos集群并用nginx反向代理负载均衡

Docker部署Nacos集群并用nginx反向代理负载均衡

首先找到Nacos官网给的Github仓库,里面有docker compose可以快速启动Nacos集群。

一. 脚本概况

我们要运行的脚本是example/cluster-hostname.yaml,可以看到里面包含了来自外界的${NACOS_VERSION}和加载外界env文件的env_file条目,于是我们可以找到本yaml所依赖的以下文件列表:

  • example/.env
  • env/mysql.env
  • env/nacos-hostname.env

二. 自定义修改

1. example/cluster-hostname.yaml

找到mysql-healthcheck-test修改为

language-yaml
1
2
3
mysql:
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}" ]

这样做的原因是防止mysql容器测试时一直报错Access denied(password: No)

2. example/.env

在后面运行docker compose时,会加载这个文件为环境变量,填入${NACOS_VERSION}${MYSQL_ROOT_PASSWORD}

language-bash
1
2
NACOS_VERSION=v2.3.0
MYSQL_ROOT_PASSWORD=1009

NACOS_VERSION的版本选多少可以参考Nacos官方的对照表

官方指出Nacos有一定向下兼容性,所以选择新一点的Nacos版本也没问题,同时,某些版本的Nacos已被指出存在部分问题

MYSQL_ROOT_PASSWORD为数据库root密码。

3. env/mysql.env

这是cluster-hostname.yamlmysql容器使用的env_file

language-bash
1
2
3
4
5
MYSQL_ROOT_PASSWORD=1009
MYSQL_DATABASE=nacos
MYSQL_USER=nacos
MYSQL_PASSWORD=nacos
LANG=C.UTF-8

MYSQL_ROOT_PASSWORD为数据库root密码,和上面那个保持一致
MYSQL_DATABASE为数据库名称
MYSQL_USER为数据库用户名
MYSQL_PASSWORD为用户(nacos)密码

4. env/nacos-hostname.env

这是cluster-hostname.yaml中3个nacos容器使用的env_file

language-bash
1
2
3
4
5
6
7
8
9
10
11
12
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=mysql
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_IDENTITY_KEY=2222
NACOS_AUTH_IDENTITY_VALUE=2xxx
NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789

关于docker nacos的环境变量,可以参考Nacos官方给的一张表格

为什么NACOS_SERVERS填的是nacos1,nacos2,nacos3,不是具体的ip地址?
为什么MYSQL_SERVICE_HOST(数据库连接地址)填的是”mysql”?
同时MYSQL_SERVICE_PORT应该填mysql容器的端口还是映射到主机的端口?
因为三个nacos容器和一个mysql在一个docker compose文件里,也就是cluster-hostname.yaml,那么在运行这个yaml文件时,docker会默认把这个yaml里所有的容器放到一个新的bridge网络中,于是,四个容器可以通过它们在这个bridge网络里的ip互相访问,同时也可以通过hostname互相访问,如果没有指明hostname,那么默认就是服务的名称(services),比如mysql的就是mysql。同时这四个容器之间互相访问的端口是容器开放的端口,而不是映射到主机的端口。

三、运行

在根目录运行docker-compose -f example/cluster-hostname.yaml up
然后浏览器就可以访问localhost:port/nacosport是三个nacos8848端口映射到主机的三个端口之一。

四、nginx反向代理,负载均衡

docker pull nginx:stable下载nginx的稳定版镜像
然后用这个镜像随便启动一个容器,把里面的以下文件copy到主机,修改后做-v映射。

  • /etc/nginx/nginx.conf
  • /etc/nginx/conf.d/default.conf

1. 配置文件修改

其中nginx.conf无需修改
default.conf参考以下示例

language-bash
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
upstream nacos-cluster {

server 172.29.0.3:8848;
server 172.29.0.4:8848;
server 172.29.0.5:8848;
}

server {

listen 80;
listen [::]:80;
server_name localhost;

#access_log /var/log/nginx/host.access.log main;

location / {

proxy_pass http://nacos-cluster;
# root /usr/share/nginx/html;
# index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {

root /usr/share/nginx/html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {

# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {

# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {

# deny all;
#}
}

主要注意两个地方,一个是

language-bash
1
2
3
4
5
6
upstream nacos-cluster {

server 172.29.0.3:8848;
server 172.29.0.4:8848;
server 172.29.0.5:8848;
}

这里面写明了3个nacos容器的ip和端口,其中ip是它们处于docker bridge小局域网中的ip,以及port也是容器服务的端口,这是因为我们最后会把nginx容器也加入这个bridge网络。

用以下命令查看三个nacos的ip

language-bash
1
2
3
4
5
6
7
8
9
10
11
C:\Users\mumu\IdeaProjects\nacos-docker>docker network ls
NETWORK ID NAME DRIVER SCOPE
fdfe3fcab913 bigdata bridge local
45d79fa3e39e bridge bridge local
2d784bdacaa1 example_default bridge local
83b9f11eccaa host host local
d138886a8b5b none null local
C:\Users\mumu\IdeaProjects\nacos-docker>docker network inspect example_default
[
.....
]

另一个是

language-bash
1
2
3
4
5
6
location / {

proxy_pass http://nacos-cluster;
# root /usr/share/nginx/html;
# index index.html index.htm;
}

这里的意思是把/的url请求(/的话基本就是所有请求了)全部转发到上面定义的upstream nacos-cluster服务器集群中。
这里默认是以轮询作为负载均衡的策略。

language-bash
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
!!!分配方式
Nginx的upstream支持5种分配方式,下面将会详细介绍,其中,前三种为Nginx原生支持的分配方式,后两种为第三方支持的分配方式:

1、轮询
轮询是upstream的默认分配方式,即每个请求按照时间顺序轮流分配到不同的后端服务器,如果某个后端服务器down掉后,能自动剔除。
upstream backend {

server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
}
2、weight
轮询的加强版,即可以指定轮询比率,weight和访问几率成正比,主要应用于后端服务器异质的场景下。
upstream backend {

server 192.168.200.131:8848 weight=1;
server 192.168.200.131:8849 weight=2;
server 192.168.200.131:8850 weight=3;
}
3、ip_hash
每个请求按照访问ip(即Nginx的前置服务器或者客户端IP)的hash结果分配,这样每个访客会固定访问一个后端服务器,可以解决session一致问题。
upstream backend {

ip_hash;
server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
}
4、fair
fair顾名思义,公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求。
upstream backend {

server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
fair;
}
5、url_hash
与ip_hash类似,但是按照访问url的hash结果来分配请求,使得每个url定向到同一个后端服务器,主要应用于后端服务器为缓存时的场景下。
upstream backend {

server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
hash $request_uri;
hash_method crc32;
}
其中,hash_method为使用的hash算法,需要注意的是:此时,server语句中不能加weight等参数。

2. 运行

参考以下命令运行(cmd版)

language-bash
1
2
3
4
5
6
7
8
docker run -id --name=nacos_nginx ^
-p 80:80 ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\nginx.conf:/etc/nginx/nginx.conf ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\conf.d\default.conf:/etc/nginx/conf.d/default.conf ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\logs:/var/log/nginx ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\html:/usr/share/nginx/html ^
--network example_default ^
nginx:stable

最后,访问localhost/nacos就可以访问nginxnginx会通过负载均衡的策略将你的请求重定向到nacos集群中的某一个。

云服务器Docker部署SpringBoot+Redis(Ubuntu)

云服务器Docker部署SpringBoot+Redis(Ubuntu)

参考文件夹结构

language-bash
1
2
3
4
5
6
7
MyTest01
├── javaDocker.sh
├── redisDocker.sh
├── Redis
│ └── data
├── SpringBoot
└── MyWeb01-SpringBoot-0.0.1-SNAPSHOT.jar

一、起手式:配置环境

1.镜像

拉取以下两个镜像

language-bash
1
2
docker pull openjdk:17
docker pull redis

二、启动Redis容器

redisDocker.sh脚本写入以下内容,然后bash运行
脚本意思是将redis数据映射到主机

language-bash
1
2
3
4
5
6
7
8
9
#!/bin/bash

containerName="RedisTest01"
RedisData="/root/MyTest01/Redis/data"

docker run -d --name "$containerName" \
-v "$RedisData":/data \
-p 6379:6379 \
redis

三、配置SpringBoot容器并简单测试

添加如下配置到application.yml

language-yaml
1
2
3
4
5
6
spring:
data:
redis:
host: redisdb
port: 6379
password:

写一个简单的测试如下

language-java
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
package com.example.myweb01springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.sql.SQLException;

@RestController
@RequestMapping("/Home")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class TestController {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@GetMapping("/Kmo")
public String test() throws SQLException {

// 设置一个键值对
redisTemplate.opsForValue().set("name", "张三");

// 获取一个键值对
String name = redisTemplate.opsForValue().get("name");

System.out.println(name);

return "Success!"+name;
}
}

然后maven打包成jar,参考文件夹结构,将jar放入指定位置。
将以下内容写入javaDocker.sh脚本并bash运行
脚本意思是,向名为MySQLTest01的容器建立网络链接(单向的),它的名字(IP,主机名)为db,于是此容器可以通过db:3306访问MySQLTest01容器的mysql服务。

language-bash
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

containerName="JavaTest01"
SpringBootPath="/root/MyTest01/SpringBoot/MyWeb01-SpringBoot-0.0.1-SNAPSHOT.jar"

docker run -d --name "$containerName" \
-p 8081:8081 \
--link RedisTest01:redisdb \
-v "$SpringBootPath":/app/your-app.jar \
openjdk:17 java -jar /app/your-app.jar

开放云服务器安全组入站规则8081端口,浏览器访问云服务器IP:8081/Home/Kmo验证。

(完)

云服务器Docker部署SpringBoot+MySQL(Ubuntu)

云服务器Docker部署SpringBoot+MySQL(Ubuntu)

参考文件夹结构

language-bash
1
2
3
4
5
6
7
MyTest01
├── javaDocker.sh
├── mysqlDocker.sh
├── MySQL
│ └── data
├── SpringBoot
└── MyWeb01-SpringBoot-0.0.1-SNAPSHOT.jar

一、起手式:配置环境

1.镜像

拉取以下两个镜像

language-bash
1
2
docker pull openjdk:17
docker pull mysql:8

二、启动Mysql容器

mysqlDocker.sh脚本写入以下内容,然后bash运行
脚本意思是将mysql数据映射到主机并设置密码为xxxx,

language-bash
1
2
3
4
5
6
7
8
9
10
#!/bin/bash

containerName="MySQLTest01"
MySQLData="/root/MyTest01/MySQL/data"

docker run -d --name "$containerName" \
-p 3306:3306 \
-v "$MySQLData":/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=xxxx \
mysql:8

在云服务器安全组开放入站规则3306端口
此时可以用你喜欢的数据库连接软件来连接这个mysql容器,并创建test01数据库和一张student表,结构随意,随便插入几条数据。

三、配置SpringBoot容器并简单测试

添加如下配置到application.yml
补充你的云服务器IP和刚才设置的密码

language-yaml
1
2
3
4
5
6
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/test01?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: xxxx

写一个简单的测试如下

language-java
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
package com.example.myweb01springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.sql.SQLException;

@RestController
@RequestMapping("/Home")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class TestController {

@Autowired
DataSource dataSource;

@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping("/Kmo")
public String test() throws SQLException {

System.out.println("默认数据源为:" + dataSource.getClass());
System.out.println("数据库连接实例:" + dataSource.getConnection());
//访问数据库user表,查询user表的数据量
Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `student`", Integer.class);
System.out.println("user 表中共有" + i + "条数据。");

return "Success!"+i;
}
}

然后本地运行打开浏览器访问localhost:8081/Home/Kmo验证是否从远程数据库取得连接。
然后在application.yml中将url的服务器IP改成db

language-yaml
1
2
3
4
5
6
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://db:3306/test01?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: xxxx

然后maven打包成jar,参考文件夹结构,将jar放入指定位置。
将以下内容写入javaDocker.sh脚本并bash运行
脚本意思是,向名为MySQLTest01的容器建立网络链接(单向的),它的名字(IP,主机名)为db,于是此容器可以通过db:3306访问MySQLTest01容器的mysql服务。

language-bash
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

containerName="JavaTest01"
SpringBootPath="/root/MyTest01/SpringBoot/MyWeb01-SpringBoot-0.0.1-SNAPSHOT.jar"

docker run -d --name "$containerName" \
-p 8081:8081 \
--link MySQLTest01:db \
-v "$SpringBootPath":/app/your-app.jar \
openjdk:17 java -jar /app/your-app.jar

开放云服务器安全组入站规则8081端口,浏览器访问云服务器IP:8081/Home/Kmo验证。

结束后记得关闭云服务器的3306入站规则

(完)

Linux+Docker部署基于Ambari的Hadoop集群

Linux+Docker部署基于Ambari的Hadoop集群

建议文档和视频一起食用。

文档链接

文档https://1138882663s-organization.gitbook.io/between-code-and-words/bigdata/ambari/da-jian-xu-ni-ji-ji-qun-yi-ji-an-zhuang-ambari

视频链接视频https://b23.tv/YdYulVJ

docker因为容器化技术和虚拟化技术的区别,部署hadoop会存在很多bug。建议使用虚拟机而不是容器。

https://www.bilibili.com/video/BV1Az4y1v7Zw/https://www.bilibili.com/video/BV1Az4y1v7Zw/

优雅地给Docker容器添加新端口

优雅地给Docker容器添加新端口

一共分为三步,停止容器和docker服务,修改配置文件,重启服务和容器。

这里只讲如何修改配置文件。

如果你是Linux环境

容器配置文件hostconfig.json 通常位于 /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json 或者 /var/snap/docker/common/var-lib-docker/containers/[hash_of_the_container]/hostconfig.json

找到PortBindings字段,以下是一个端口的格式例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"PortBindings": {
"8080/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
],
"8088/tcp": [
{
"HostIp": "",
"HostPort": "8088"
}
]
},

如果不起作用,建议同时修改下面提到的config.v2.json

如果你是windws+wsl2环境

那么你需要修改两个文件,hostconfig.jsonconfig.v2.json,它们都位于/mnt/wsl/docker-desktop-data/data/docker/<containerID>下。

hostconfig.json文件修改和linux的一样。

config.v2.json需要修改以下两个字段

1
2
3
"ExposedPorts":{"8080/tcp":{},"8088/tcp":{}}

"Ports":{"8080/tcp":[{"HostIp":"0.0.0.0","HostPort":"8080"}],"8088/tcp":[{"HostIp":"0.0.0.0","HostPort":"8088"}]}

参考资料

How do I assign a port mapping to an existing Docker container? - Stack Overflowhttps://stackoverflow.com/questions/19335444/how-do-i-assign-a-port-mapping-to-an-existing-docker-containerAdding new exposed ports to existing docker container (Windows/WSL 2) | by LifeOnKeyboardBlog | Mediumhttps://medium.com/@lifeonkeyboardblog/adding-new-exposed-ports-to-existing-docker-container-windows-wsl-2-3cfe58d551e

Docker容器中删除文件后,大小不减反增怎么办?

Docker容器中删除文件后,大小不减反增怎么办?

Docker的镜像是由多层存储结构组成的,每一层都是只读的,所以您无法删除之前层的操作。

但是可以通过以下步骤达到一样的效果。

假设你从原始镜像a中创建了容器b。

现在你在容器b中删除了一些东西。

您可以使用docker export命令将容器的文件系统导出为一个tar文件:

1
docker export -o my.tar containerID

然后,使用docker import命令从这个tar文件导入为一个新的镜像:

1
docker import my.tar new-image

此时这个new-image镜像就摆脱了旧镜像的历史层,大小也会相应大大减少。

但是你可能会失去一些东西:环境变量、端口映射、镜像的历史记录和层级结构、镜像的标签和版本号、镜像的创建时间和作者、容器的启动命令和参数等等。