mirror of
https://github.com/xiaoxinpro/nginx-proxy-manager-zh.git
synced 2025-01-22 21:08:13 -05:00
199 lines
6.8 KiB
Markdown
199 lines
6.8 KiB
Markdown
# Advanced Configuration
|
|
|
|
## Best Practice: Use a Docker network
|
|
|
|
For those who have a few of their upstream services running in Docker on the same Docker
|
|
host as NPM, here's a trick to secure things a bit better. By creating a custom Docker network,
|
|
you don't need to publish ports for your upstream services to all of the Docker host's interfaces.
|
|
|
|
Create a network, ie "scoobydoo":
|
|
|
|
```bash
|
|
docker network create scoobydoo
|
|
```
|
|
|
|
Then add the following to the `docker-compose.yml` file for both NPM and any other
|
|
services running on this Docker host:
|
|
|
|
```yml
|
|
networks:
|
|
default:
|
|
external:
|
|
name: scoobydoo
|
|
```
|
|
|
|
Let's look at a Portainer example:
|
|
|
|
```yml
|
|
version: '3'
|
|
services:
|
|
|
|
portainer:
|
|
image: portainer/portainer
|
|
privileged: true
|
|
volumes:
|
|
- './data:/data'
|
|
- '/var/run/docker.sock:/var/run/docker.sock'
|
|
restart: unless-stopped
|
|
|
|
networks:
|
|
default:
|
|
external:
|
|
name: scoobydoo
|
|
```
|
|
|
|
Now in the NPM UI you can create a proxy host with `portainer` as the hostname,
|
|
and port `9000` as the port. Even though this port isn't listed in the docker-compose
|
|
file, it's "exposed" by the Portainer Docker image for you and not available on
|
|
the Docker host outside of this Docker network. The service name is used as the
|
|
hostname, so make sure your service names are unique when using the same network.
|
|
|
|
## Docker Healthcheck
|
|
|
|
The `Dockerfile` that builds this project does not include a `HEALTHCHECK` but you can opt in to this
|
|
feature by adding the following to the service in your `docker-compose.yml` file:
|
|
|
|
```yml
|
|
healthcheck:
|
|
test: ["CMD", "/bin/check-health"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
```
|
|
|
|
## Docker Secrets
|
|
|
|
This image supports the use of Docker secrets to import from file and keep sensitive usernames or passwords from being passed or preserved in plaintext.
|
|
|
|
You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name.
|
|
|
|
```yml
|
|
version: "3.7"
|
|
|
|
secrets:
|
|
# Secrets are single-line text files where the sole content is the secret
|
|
# Paths in this example assume that secrets are kept in local folder called ".secrets"
|
|
DB_ROOT_PWD:
|
|
file: .secrets/db_root_pwd.txt
|
|
MYSQL_PWD:
|
|
file: .secrets/mysql_pwd.txt
|
|
|
|
services:
|
|
app:
|
|
image: 'jc21/nginx-proxy-manager:latest'
|
|
restart: unless-stopped
|
|
ports:
|
|
# Public HTTP Port:
|
|
- '80:80'
|
|
# Public HTTPS Port:
|
|
- '443:443'
|
|
# Admin Web Port:
|
|
- '81:81'
|
|
environment:
|
|
# These are the settings to access your db
|
|
DB_MYSQL_HOST: "db"
|
|
DB_MYSQL_PORT: 3306
|
|
DB_MYSQL_USER: "npm"
|
|
# DB_MYSQL_PASSWORD: "npm" # use secret instead
|
|
DB_MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
|
DB_MYSQL_NAME: "npm"
|
|
# If you would rather use Sqlite uncomment this
|
|
# and remove all DB_MYSQL_* lines above
|
|
# DB_SQLITE_FILE: "/data/database.sqlite"
|
|
# Uncomment this if IPv6 is not enabled on your host
|
|
# DISABLE_IPV6: 'true'
|
|
volumes:
|
|
- ./data:/data
|
|
- ./letsencrypt:/etc/letsencrypt
|
|
secrets:
|
|
- MYSQL_PWD
|
|
depends_on:
|
|
- db
|
|
db:
|
|
image: jc21/mariadb-aria
|
|
restart: unless-stopped
|
|
environment:
|
|
# MYSQL_ROOT_PASSWORD: "npm" # use secret instead
|
|
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
|
|
MYSQL_DATABASE: "npm"
|
|
MYSQL_USER: "npm"
|
|
# MYSQL_PASSWORD: "npm" # use secret instead
|
|
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
|
volumes:
|
|
- ./data/mysql:/var/lib/mysql
|
|
secrets:
|
|
- DB_ROOT_PWD
|
|
- MYSQL_PWD
|
|
```
|
|
|
|
|
|
## Disabling IPv6
|
|
|
|
On some Docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log:
|
|
|
|
> Address family not supported by protocol
|
|
|
|
The easy fix is to add a Docker environment variable to the Nginx Proxy Manager stack:
|
|
|
|
```yml
|
|
environment:
|
|
DISABLE_IPV6: 'true'
|
|
```
|
|
|
|
|
|
## Custom Nginx Configurations
|
|
|
|
If you are a more advanced user, you might be itching for extra Nginx customizability.
|
|
|
|
NPM has the ability to include different custom configuration snippets in different places.
|
|
|
|
You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
|
|
|
|
- `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
|
|
- `/data/nginx/custom/http_top.conf`: Included at the top of the main http block
|
|
- `/data/nginx/custom/http.conf`: Included at the end of the main http block
|
|
- `/data/nginx/custom/stream.conf`: Included at the end of the main stream block
|
|
- `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
|
|
- `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
|
|
- `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block
|
|
- `/data/nginx/custom/server_stream_tcp.conf`: Included at the end of every TCP stream server block
|
|
- `/data/nginx/custom/server_stream_udp.conf`: Included at the end of every UDP stream server block
|
|
|
|
Every file is optional.
|
|
|
|
|
|
## X-FRAME-OPTIONS Header
|
|
|
|
You can configure the [`X-FRAME-OPTIONS`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) header
|
|
value by specifying it as a Docker environment variable. The default if not specified is `deny`.
|
|
|
|
```yml
|
|
...
|
|
environment:
|
|
X_FRAME_OPTIONS: "sameorigin"
|
|
...
|
|
```
|
|
|
|
## SSL Passthrough
|
|
|
|
SSL Passthrough will allow you to proxy a server without [SSL termination](https://en.wikipedia.org/wiki/TLS_termination_proxy). This means the SSL encryption of the server will be passed right through the proxy, retaining the original certificate.
|
|
|
|
Because of the SSL encryption the proxy does not know anything about the traffic and it just relies on an SSL feature called [Server Name Indication](https://en.wikipedia.org/wiki/Server_Name_Indication) to know where to send this network packet. This also means if the client does not provide this additional information, accessing the site through the proxy won't be possible. But most modern browsers include this information a HTTPS requests.
|
|
|
|
Due to nginx constraints using SSL Passthrough comes with **a performance penalty for other hosts**, since all hosts (including normal proxy hosts) now have to pass through this additional step and basically being proxied twice. If you want to retain the upstream SSL certificate but do not need your service to be available on port 443, it is recommended to use a stream host instead.
|
|
|
|
To enable SSL Passthrough on your npm instance you need to do two things: add the environment variable `ENABLE_SSL_PASSTHROUGH` with the value `"true"`, and expose port 444 instead of 443 to the outside as port 443.
|
|
|
|
```yml
|
|
version: '3'
|
|
services:
|
|
app:
|
|
...
|
|
ports:
|
|
- '80:80'
|
|
- '81:81'
|
|
- '443:444' # Expose internal port 444 instead of 443 as SSL port
|
|
environment:
|
|
...
|
|
ENABLE_SSL_PASSTHROUGH: "true" # Enable SSL Passthrough
|
|
...
|
|
``` |