Jinnrry / PMail

Private EMail Server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

主机使用nginx,pmail使用docker容器部署,如何才能成功部署

muyiacc opened this issue · comments

请说明问题 / Describe the bug
主机使用nginx,pmail使用docker容器部署,结果部署最后一步acme验证失败,如何配置nginx或者如何才能成功部署pmail(不采用手动管理证书,不方便)。

如何复现 / To Reproduce
Steps to reproduce the behavior:
1.启动docekr容器,采用docker-compose方式。
2.编写nginx配置文件,根据之前的issues #61 作为参考编写nginx.conf。
3.启动docker容器,sudo docker compose up, 使用ip:port 进入web端,执行到最后一步,失败。

你预期的行为 / Expected behavior
主机使用nginx,pmail使用容器,部署成功。

贴上你的配置文件 / Program configuration file contents

docker-compose.yml
version: '3.9'
services:
    pmail:
        container_name: pmail
        image: 'ghcr.io/jinnrry/pmail:latest'
        volumes:
            - './config:/work/config'
        ports:
            # pop
            - '110:110'
            - '995:995'
            # smtp
            - '25:25'
            - '465:465'
            # web访问
            - '8780:80'
            - '8781:443'
        restart: unless-stopped
nginx.conf
server {
    listen 110;  # 监听SMTP端口
    server_name pop.seektao.cc;

    location / {
        proxy_pass http://172.19.0.3:110;  # 代理到pmail的SMTP端口
    }
}

server {
    listen 25;  # 监听POP3端口
    server_name smtp.seektao.cc;

    location / {
        proxy_pass http://172.19.0.3:25;  # 代理到pmail的POP3端口
    }
}
server {
    listen 80;
    server_name pmail.seektao.cc;
    return 301 https://pmail.seektao.cc$request_uri;
}

server {  
    listen 443 ssl http2;  
    server_name pmail.seektao.cc;  
  
    # SSL 证书配置  
    ssl_certificate /etc/letsencrypt/live/seektao.cc/fullchain.pem;  
    ssl_certificate_key /etc/letsencrypt/live/seektao.cc/privkey.pem;  
  
    # 安全设置  
    ssl_protocols TLSv1.2 TLSv1.3;  
    ssl_ciphers HIGH:!aNULL:!MD5;  
    ssl_prefer_server_ciphers on;

    # 反向代理  
    location / {  
        proxy_pass http://172.19.0.3:80/;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        proxy_set_header X-Forwarded-Proto https;  
    }    
  
    location /.well-known/{
        proxy_pass  http://172.19.0.3:80;
        proxy_redirect     off;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

    # 日志配置  
    access_log /var/log/nginx/chatgpt.seektao.cc.access.log;  
    error_log /var/log/nginx/chatgpt.seektao.cc.error.log;  
}

日志信息 / Log

log
pmail  | 2024/03/28 19:12:05 [INFO] acme: Registering account for i@seektao.cc
pmail  | 2024/03/28 19:12:06 [INFO] [smtp.seektao.cc, pmail.seektao.cc, pop.seektao.cc] acme: Obtaining bundled SAN certificate
pmail  | 2024/03/28 19:12:11 [INFO] [pmail.seektao.cc] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568977
pmail  | 2024/03/28 19:12:11 [INFO] [pop.seektao.cc] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568987
pmail  | 2024/03/28 19:12:11 [INFO] [smtp.seektao.cc] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568997
pmail  | 2024/03/28 19:12:11 [INFO] [pmail.seektao.cc] acme: Could not find solver for: tls-alpn-01
pmail  | 2024/03/28 19:12:11 [INFO] [pmail.seektao.cc] acme: use http-01 solver
pmail  | 2024/03/28 19:12:11 [INFO] [pop.seektao.cc] acme: Could not find solver for: tls-alpn-01
pmail  | 2024/03/28 19:12:11 [INFO] [pop.seektao.cc] acme: use http-01 solver
pmail  | 2024/03/28 19:12:11 [INFO] [smtp.seektao.cc] acme: Could not find solver for: tls-alpn-01
pmail  | 2024/03/28 19:12:11 [INFO] [smtp.seektao.cc] acme: use http-01 solver
pmail  | 2024/03/28 19:12:11 [INFO] [pmail.seektao.cc] acme: Trying to solve HTTP-01
pmail  | 2024/03/28 19:12:25 [INFO] [pop.seektao.cc] acme: Trying to solve HTTP-01
pmail  | 2024/03/28 19:12:41 [INFO] [smtp.seektao.cc] acme: Trying to solve HTTP-01
pmail  | 2024/03/28 19:13:23 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568977
pmail  | 2024/03/28 19:13:26 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568987
pmail  | 2024/03/28 19:13:30 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/331685568997

server {
    listen 110;  # 监听SMTP端口
    server_name pop.seektao.cc;

    location / {
        proxy_pass http://172.19.0.3:110;  # 代理到pmail的SMTP端口
    }
}

server {
    listen 25;  # 监听POP3端口
    server_name smtp.seektao.cc;

    location / {
        proxy_pass http://172.19.0.3:25;  # 代理到pmail的POP3端口
    }
}
server {
    listen 80;
    server_name pmail.seektao.cc;
    location /.well-known/{
        proxy_pass  http://172.19.0.3:80;
        proxy_redirect     off;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
    location /{
        return 301 https://pmail.seektao.cc$request_uri;
    }
}

server {  
    listen 443 ssl http2;  
    server_name pmail.seektao.cc;  
  
    # SSL 证书配置  
    ssl_certificate /etc/letsencrypt/live/seektao.cc/fullchain.pem;  
    ssl_certificate_key /etc/letsencrypt/live/seektao.cc/privkey.pem;  
  
    # 安全设置  
    ssl_protocols TLSv1.2 TLSv1.3;  
    ssl_ciphers HIGH:!aNULL:!MD5;  
    ssl_prefer_server_ciphers on;

    # 反向代理  
    location / {  
        proxy_pass http://172.19.0.3:80/;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        proxy_set_header X-Forwarded-Proto https;  
    }    
  
    location /.well-known/{
        proxy_pass  http://172.19.0.3:80;
        proxy_redirect     off;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

    # 日志配置  
    access_log /var/log/nginx/chatgpt.seektao.cc.access.log;  
    error_log /var/log/nginx/chatgpt.seektao.cc.error.log;  
}

改成这样

你这个pop3 和smtp代理也不对,pop3和smtp跟http一样都是应用层协议,你这个配置是http协议的代理,这样肯定是有问题的。

nginx要使用ngx_stream_core_module模块才能代理tcp流量

我改成这样对吗

gpt问一下,需要添加stream,而且需要放在主配置nginx.conf中,之前的配置我是放在conf.d/pmail.conf下的
现在的配置如下

conf.d/pmail.conf

    server {
        listen 80;
        server_name pmail.seektao.cc;
        
        location /.well-known/ {
            proxy_pass http://172.19.0.3:80;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {
            return 301 https://pmail.seektao.cc$request_uri;
        }
    }

    server {
        listen 443 ssl http2;
        server_name pmail.seektao.cc;

        # SSL 证书配置
        ssl_certificate /etc/letsencrypt/live/seektao.cc/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seektao.cc/privkey.pem;

        # 安全设置
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # 反向代理
        location / {
            proxy_pass http://172.19.0.3:80/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }

        location /.well-known/ {
            proxy_pass http://172.19.0.3:80;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 日志配置
        access_log /var/log/nginx/chatgpt.seektao.cc.access.log;
        error_log /var/log/nginx/chatgpt.seektao.cc.error.log;
    }

nginx.conf 最后添加

stream {
    server {
        listen 25;
        proxy_pass 172.19.0.3:25;
    }

    server {
        listen 110;
        proxy_pass 172.19.0.3:110;
    }
}

按照上述的改动,acme还是失败了

    server {
        listen 80;
        server_name *.seektao.cc;
        
        location /.well-known/ {
            proxy_pass http://172.19.0.3:80;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {
            return 301 https://pmail.seektao.cc$request_uri;
        }
    }

域名改成通配符

还有问题的话把nginx 404日志打开,看看还有那个路由没转发过去

对了还有个问题,昨天加了这个之后容器就无法启动了,提示端口被占用

`
stream {
server {
listen 25;
proxy_pass 172.19.0.3:25;
}

server {
    listen 110;
    proxy_pass 172.19.0.3:110;
}

}
`

对了还有个问题,昨天加了这个之后容器就无法启动了,提示端口被占用

`
stream {
server {
listen 25;
proxy_pass 172.19.0.3:25;
}

server {
    listen 110;
    proxy_pass 172.19.0.3:110;
}

}
`

nginx.conf 的 stream 模块加上25 110端口之后会占用他们,就跟80 443一样,如果先启动nginx,容器就无法启动,如果先启动容器,nginx提示端口被占用,如下,nginx的错误日志

2024/03/29 13:39:37 [notice] 36011#36011: signal process started
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:25 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:110 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:25 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:110 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:25 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:110 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:25 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:110 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:25 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: bind() to 0.0.0.0:110 failed (98: Address already in use)
2024/03/29 13:39:37 [emerg] 927#927: still could not bind()

方案1:ngixn也放docker里面,然后使用容器名访问
方案2:docker把PMail容器的25、110等端口映射到其他端口去
方案3:docker仅绑定localhost的端口,nginx仅绑定外网ip端口

另外,你这个172.19.0.3也不对吧,按你说的,你nginx在物理机上,PMail在容器里,你这个172.19.0.3IP真能请求通?

还有几个问题:
1、你docker都把 110、995、25、465端口暴露出来了,干嘛还要nginx代理呀
2、你docker把80端口映射到了8780,你nginx代理端口还写80,这肯定不通啊。
3、如果你说的物理机和docker机器是同一台机器的话,物理机上用172.19.0.3这样的ip访问大概率是不通的,除非你自己做过什么网络设置。你如果不懂docker的网络管理的话,按你现在的配置直接写127.0.0.1:8780

   // 其他pop3 smtp啥的代理删了,不需要,只需要nginx代理http、https流量
    server {
        listen 80;
        server_name *.seektao.cc;
        
        location /.well-known/ {
            proxy_pass http://127.0.0.1:8780;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {
            return 301 https://pmail.seektao.cc$request_uri;
        }
    }
server {
        listen 443 ssl http2;
        server_name pmail.seektao.cc;

        # SSL 证书配置
        ssl_certificate /etc/letsencrypt/live/seektao.cc/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seektao.cc/privkey.pem;

        # 安全设置
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # 反向代理
        location / {
            proxy_pass http://127.0.0.1:8781/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }

        location /.well-known/ {
            proxy_pass http://127.0.0.1:8781/;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 日志配置
        access_log /var/log/nginx/chatgpt.seektao.cc.access.log;
        error_log /var/log/nginx/chatgpt.seektao.cc.error.log;
    }


那nginx.conf 这个要删么

stream {
    server {
        listen 25;
        proxy_pass 172.19.0.3:25;
    }

    server {
        listen 110;
        proxy_pass 172.19.0.3:110;
    }
}

那nginx.conf 这个要删么

stream {
    server {
        listen 25;
        proxy_pass 172.19.0.3:25;
    }

    server {
        listen 110;
        proxy_pass 172.19.0.3:110;
    }
}

要删

我放弃治疗了,还是手动管理证书吧,谢谢你的回答