Closed GlowManCZ closed 5 years ago
The nginx reverse proxy settings are correct.
It is something different to use a dockerized Nginx like jwilders. You cannot copy and paste the docs here.
There are also several things you need to make sure don’t break. Like the unencrypted autoconfig or, if needed, the passing of acme-challenges, setting the correct headers etc.
If you think you didn’t break any of those, a PR is welcome. :)
I'm already working on the documentation. Should I close the issue and then make a pull request to docs ? Or I have to leave open ?
Create a PR for us to check it there. :)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@GlowManCZ any progress? I am looking for a doc about it because I want to integrate mailcow-dockerized to my existing environment, that uses jwilder/nginx-proxy
.
I would like this as well.
Would be nice if an documentation exist. :-)
@GlowManCZ any progress? I am looking for a doc about it because I want to integrate mailcow-dockerized to my existing environment, that uses
jwilder/nginx-proxy
.
@Heziode try this: set in mailcow.conf:
MAILCOW_HOSTNAME=${domain}
[...]
HTTP_PORT=8080
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1
[...]
SKIP_LETS_ENCRYPT=y
[...]
in docker-compose.yml in section nginx-mailcow add in environment:
- HTTPS_METHOD=noredirect
- VIRTUAL_HOST=${domain},autoconfig.${domain},autodiscover.${domain}
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=${domain},autoconfig.${domain},autodiscover.${domain}
- LETSENCRYPT_EMAIL=${yourEmailForLE}
and in section nginx-mailcow add in networks:
mailcow-network:
aliases:
- nginx
proxy-network:
and in section networks add:
networks:
mailcow-network:
[...]
proxy-network:
external:
name: ${your_nginx-proxy_network_name}
[...]
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@fstangenberger
Sorry for the delay.
With your config I can access to mailcow but in HTTP. Not in HTTPS.
@Heziode https is served by nginx-proxy. In mailcow.conf is a hint in section HTTP/S Bindings:
# You should use HTTPS, but in case of SSL offloaded reverse proxies:
HTTP_PORT=8080
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1
In all cases of the configuration an upstream is created by nginx-gen which points to http of mailcowdockerized_nginx-mailcow_1:
server 172.19.0.20:8080;
(in conf.d/default.conf)
These upstream is used for Port 80 and 443 as proxy_pass. The proxy authorizes the https request and send it via http to mailcow_nginx.
when I try to acces trough HTTPS, I get an error 500.
when I try to acces trough HTTPS, I get an error 500.
Are there log entries in nginx-proxy log for such a request? It seems, mailcow isn't in the network of nginx-proxy. 'proxy-network' is the name of the network of mailcow and nginx-proxy.
To be sure about what we talking about, here is the architecture of my ecosystem:
When you talk about "nginx-proxy" do you mean "nginx-mailcow" or my "nginx-proxy" ?
When I try to access trough HTTPS, I see the request on nginx-proxy but it returns 500 here, nginx-mailcow log do not show everything.
When I try to access trough HTTP, I see the request on nginx-proxy and on nginx-mailcow logs (and I get the page).
I mean nginx-proxy from jwilder. Are there an entry in conf.d/default.conf for https?
The part of default.conf of nginx-proxy related to mailcow are:
# autoconfig.mail.mysite.local
upstream autoconfig.mail.mysite.local {
## Can be connected with "proxy-network" network
# mailcowdockerized_nginx-mailcow_1
server 172.33.0.2:8080;
# Cannot connect to network of this container
server 127.0.0.1 down;
}
server {
server_name autoconfig.mail.mysite.local;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
location / {
proxy_pass http://autoconfig.mail.mysite.local;
}
}
server {
server_name autoconfig.mail.mysite.local;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
# autodiscover.mail.mysite.local
upstream autodiscover.mail.mysite.local {
## Can be connected with "proxy-network" network
# mailcowdockerized_nginx-mailcow_1
server 172.33.0.2:8080;
# Cannot connect to network of this container
server 127.0.0.1 down;
}
server {
server_name autodiscover.mail.mysite.local;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
location / {
proxy_pass http://autodiscover.mail.mysite.local;
}
}
server {
server_name autodiscover.mail.mysite.local;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
# mail.mysite.local
upstream mail.mysite.local {
## Can be connected with "proxy-network" network
# mailcowdockerized_nginx-mailcow_1
server 172.33.0.2:8080;
# Cannot connect to network of this container
server 127.0.0.1 down;
}
server {
server_name mail.mysite.local;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
location / {
proxy_pass http://mail.mysite.local;
}
}
server {
server_name mail.mysite.local;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
The same entry of "location /{proxy-pass ...}" of port 80 has to be in the section of port 443. Perhaps without "return 500"
Will have a look tomorrow on the laptop.
Yep, but I'm not the one who makes the file, it's done automatically I can't change it manually, because it will be overwrited by the auto-conf.
The nginx-mailcow in docker-compose.yml:
nginx-mailcow:
depends_on:
- sogo-mailcow
- php-fpm-mailcow
- redis-mailcow
image: nginx:mainline-alpine
command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
envsubst < /etc/nginx/conf.d/templates/sogo.template > /etc/nginx/conf.d/sogo.active &&
envsubst < /etc/nginx/conf.d/templates/sogo_eas.template > /etc/nginx/conf.d/sogo_eas.active &&
. /etc/nginx/conf.d/templates/sogo.auth_request.template.sh > /etc/nginx/conf.d/sogo_proxy_auth.active &&
nginx -qt &&
until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
until ping sogo -c1 > /dev/null; do sleep 1; done &&
until ping redis -c1 > /dev/null; do sleep 1; done &&
until ping rspamd -c1 > /dev/null; do sleep 1; done &&
exec nginx -g 'daemon off;'"
environment:
#- HTTPS_METHOD=noredirect
- HTTPS_METHOD=redirect
- HTTP_FORWARDED_COUNT=1
- VIRTUAL_HOST=${MAILCOW_HOSTNAME},autoconfig.${MAILCOW_HOSTNAME},autodiscover.${MAILCOW_HOSTNAME}
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=${MAILCOW_HOSTNAME},autoconfig.${MAILCOW_HOSTNAME},autodiscover.${MAILCOW_HOSTNAME}
- LETSENCRYPT_EMAIL=support@mysite.local
- PORT=8080
##
- HTTPS_PORT=${HTTPS_PORT:-443}
- HTTP_PORT=${HTTP_PORT:-80}
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
- TZ=${TZ}
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
volumes:
- ./data/web:/web:ro
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/assets/ssl/:/etc/ssl/mail/:ro
- ./data/conf/nginx/:/etc/nginx/conf.d/:rw
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
ports:
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
restart: always
dns:
- ${IPV4_NETWORK:-172.22.1}.254
networks:
mailcow-network:
aliases:
- nginx
proxy-network:
Try it with "HTTPS_METHOD=noredirect"
This do not change everythings.
You're right. HTTPS_METHOD doesn't matter in this case. Try without "PORT=8080"
Likewise, it doesn't change anythings.
In mailcow.conf you have both ports changed? 80 and 443 is served by nginx-proxy. So mailcow has to use other ones (8080, 8443).
In default.conf of nginx-proxy: with "HTTPS_METHOD=redirect" port 80 only returns a 301 to https and port 443 has still:
location / {
proxy_pass http://${MAILCOW_HOSTNAME};
}
In mailcow.conf you have both ports changed? 80 and 443 is served by nginx-proxy. So mailcow has to use other ones (8080, 8443).
Yep, it is:
# ------------------------------
# HTTP/S Bindings
# ------------------------------
# You should use HTTPS, but in case of SSL offloaded reverse proxies:
HTTP_PORT=8080
#HTTP_BIND=0.0.0.0
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
#HTTPS_BIND=0.0.0.0
HTTPS_BIND=127.0.0.1
# And I have also change
SKIP_LETS_ENCRYPT=y
In default.conf of nginx-proxy: with "HTTPS_METHOD=redirect" port 80 only returns a 301 to https and port 443 has still:
location / { proxy_pass http://${MAILCOW_HOSTNAME}; }
Yep, it must do this but it don't. The conf generated for my website and api work like you mention, but for mailcow, it doesn't generate the good config.
Hm. HTTP_FORWARDED_COUNT are not used by mailcow, i believe. ${MAILCOW_HOSTNAME} is "mail.mysite.local" in mailcow.conf? Is 8443 used by another host? Have you altered nginx_gen.tmpl from nginx-proxy? When you delete default.conf what's the log of nginx_gen look like? Can you provide the docker-compose.yml of the nginx_proxy? Incl. nginx_gen.
For an fast and graphical overview of all docker related stuff I recommend portainer: https://mailcow.github.io/mailcow-dockerized-docs/third_party-portainer/
HTTP_FORWARDED_COUNT are not used by mailcow, i believe.
Ok.
${MAILCOW_HOSTNAME} is "mail.mysite.local" in mailcow.conf?
Yes, it is.
Is 8443 used by another host?
Nope, it is only used by nginx-mailcow
.
Have you altered nginx_gen.tmpl from nginx-proxy?
No, I do not know this file. Where is it located ?
When you delete default.conf what's the log of nginx_gen look like?
Which default.conf
? Where is it located ?
Can you provide the docker-compose.yml of the nginx_proxy? Incl. nginx_gen.
What do you mean with nginx_gen
? nginx-mailcow
or nginx-proxy
?
docker-compose.yml
of my app:
version: '3.7'
services:
api:
build: .
image: strapi/strapi
hostname: mysite
container_name: mysite
environment:
- APP_NAME=mysite
- DATABASE_CLIENT=mongo
- DATABASE_HOST=mysite-db
- DATABASE_PORT=27017
- DATABASE_NAME=mysite
- DATABASE_USERNAME=root
- DATABASE_PASSWORD=********
- DATABASE_SSL=false
- DATABASE_AUTHENTICATION_DATABASE=
- HOST=api.mysite.local
# Var related to reverse-proxy
- VIRTUAL_HOST=api.mysite.local
- HTTPS_METHOD=redirect
- HTTP_FORWARDED_COUNT=1
- LETSENCRYPT_HOST=api.mysite.local
- LETSENCRYPT_EMAIL=support@mysite.local
- PORT=1337
ports:
- 1337:1337
volumes:
- "${PWD}/mysite:/usr/src/api/mysite"
networks:
- proxy-network
depends_on:
- db
- nginx-proxy
links:
- db
db:
image: mongo
hostname: mysite-db
container_name: mysite-db
environment:
- MONGO_INITDB_DATABASE=mysite
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=********
volumes:
- "${PWD}/data/db:/data/db"
networks:
- proxy-network
ports:
- 27017:27017
nginx-proxy:
image: jwilder/nginx-proxy:alpine
hostname: mysite-proxy
container_name: mysite-proxy
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- "${PWD}/data/conf.d:/etc/nginx/conf.d/"
- "${PWD}/data/nginx_html:/usr/share/nginx/html"
- "${PWD}/data/vhost.d:/etc/nginx/vhost.d"
- "${PWD}/data/certs:/etc/nginx/certs"
- "${PWD}/data/dhparam.pem:/etc/nginx/dhparam/"
networks:
- proxy-network
networks:
proxy-network:
name: proxy-network
driver: bridge
ipam:
driver: default
config:
- subnet: "172.33.0.0/16"
For an fast and graphical overview of all docker related stuff I recommend portainer
Indeed, it sounds very convinient, maybe also in addition of Traefik (I'm not using either of them right now).
In the documentation of nginx-proxy of jwilder (https://github.com/jwilder/nginx-proxy), it says:
nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
Please have a closer look at this documentation. In section "Multipe Ports":
If your container exposes multiple ports, nginx-proxy will default to the service running on port 80. If you need to specify a different port, you can set a VIRTUAL_PORT env var to select a different one.
You can try to set VIRTUAL_PORT=8443 instead of VIRTUAL_PORT=8080 in the docker-compose.yml of mailcow.
I use separate containers (section "Separate Containers"): nginx-proxy: image: nginx:latest nginx-gen:image: jwilder/docker-gen:latest nginx-le:image: jrcs/letsencrypt-nginx-proxy-companion:latest (for letsencrypt)
For my separate nginx_gen container I have to use nginx.tmpl like mentioned in the documentation.
As you can see, I only use jwilder/nginx-proxy:alpine
that wrappe all.
You can try to set VIRTUAL_PORT=8443 instead of VIRTUAL_PORT=8080 in the docker-compose.yml of mailcow.
When I do that, I get error 400 when I try to access from HTTP, with message: The plain HTTP request was sent to HTTPS port When I try to access from HTTPS, I get error 500.
... and with VIRTUAL_PROTO=https ? http should redirect via 301 to https
perhaps you can try to use separate containers
... and with VIRTUAL_PROTO=https ? http should redirect via 301 to https
No change when I try to access from HTTPS.
I try to access from HTTP, I can access to mailcow, but not in HTTPS.
It give me this conf:
server {
server_name mail.mysite.local;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
location / {
proxy_pass https://mail.mysite.local;
}
}
server {
server_name mail.mysite.local;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
perhaps you can try to use separate containers
Yep, but it is weird that it do not work like this…
VIRTUAL_PROTO=https has to be set with VIRTUAL_PORT=8443
Btw: To use the var LETSENCRYPT_HOST you have to use the jrcs/letsencrypt-nginx-proxy-companion container, haven't you?
VIRTUAL_PROTO=https has to be set with VIRTUAL_PORT=8443
Of course, that's what I did.
Btw: To use the var LETSENCRYPT_HOST you have to use the jrcs/letsencrypt-nginx-proxy-companion container, haven't you?
In fact, I do not use letsencryt in dev. When I dev (so, in local), I use mkcert for local dev. In production, I will use let's encrypt.
For live it's also better to use splitted nginx-proxy/ docker-gen. Then nginx-proxy is reachable from the internet while docker-gen with docker.sock ist not.
Actually, your default.conf is build with only one port. I don't see the reason, why. You can use an own conf for your site next to default.conf. There you can add "location /" for 443 like it's done for 80 in default.conf.
With nginx-proxy + docker-gen and default nginx_gen.tmpl, I have the same result. 500 on HTTPS.
I got it! I didn't put the certificates in the right place. I have put it in certs for nginx-mailcow, but I must put it the nginx exposed to the door, so nginx-proxy.
Right now, it's work. I need some experiment, but I (retry with the one nginx container) to check if certs is the only issue.
Great!
I use the jrcs/letsencrypt-nginx-proxy-companion and therefor I set a cronjob to sync the newest cert from nginx-proxy to mailcow:
0 3 * * * root /usr/bin/rsync -a ${NGINX_PROXY_ROOT}/certs/${MAILCOW_HOSTNAME}/fullchain.pem ${NGINX_PROXY_ROOT}/certs/${MAILCOW_HOSTNAME}/cert.pem ${NGINX_PROXY_ROOT}/certs/${MAILCOW_HOSTNAME}/key.pem ${MAILCOW_ROOT}/data/assets/ssl
With single container, it works. So, we simply need to put certificates in the right place (reverse proxy exposed to internet), and add environement variable related to reverse proxy (the one that is exposed to internet) on the nginx-mailcow.
I use the jrcs/letsencrypt-nginx-proxy-companion and therefor I set a cronjob to sync the newest cert from nginx-proxy to mailcow:
Have you arrived to work with let's encrypt on localhost ?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hi @andryyy I thought it would not be a bad idea to add the jwilder / nginx-proxy settings documentation. The settings that are in the documentation are not working on 100% If you agree with me, I can write something about it