
背景
只想把网站部署在docker上,也就是all in docker
说明
使用nginx进行不同域名转发到不同的docker容器项目;
docker的通信网上大多是通过映射端口到宿主机来实现,如果你没有宿主机与docker通信的需要,则没有需要这样做。
单单docker之间的通信的话,使用docker network(也即docker的子网)即可实现。
只要通信的两个docker加入了同一个docker的子网即可使用别名通信,
比如这样 http://docker1:80 其它的同子网的容器就可以这样访问到别名为docker1的容器。
宿主机的80和443端口则由nginx的docker容器统一管理,以下是我一个实际案例的过程。
docker compose
我这里使用docker compose来创建容器,使用命令也是可以的,创建容器时使用 --net 参数加入子网即可
以下是从docker compose官方示例抄来的wordpress示例
services:
# 这个wpdb就是子网里的别名,如果你网络里有同名的建议修改
wpdb:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10.6.4-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
volumes:
- wp_data:/var/www/html
depends_on:
- wpdb
# 这里暴露80端口是在子网里面暴露与nginx容器通信的,宿主机访问不到
# 不添加也是可以的,wordpress容器默认暴露80端口,针对你使用的镜像自行选择是否加上
expose:
- 80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
nginx:
# 使用alpine的镜像,占用更小
image: nginx:alpine
# 映射端口:容器端口
ports:
- 443:443
- 80:80
# 依赖,以下容器必须先启动
depends_on:
- wordpress
# 这段作用是加入已有的子网,name写你已存在的子网名
networks:
defalut:
external: true
name: default-network
volumes:
db_data:
wp_data:
由于我们是使用docker nginx来转发wordpress的请求,所以除了nginx其余不必映射到宿主机,nginx的配置可能不对,自己看需要改。
还有networks的配置,如果没有的话,docker compose会自动创建一个新的子网,以docker-compose.yml在的文件夹名后加_dafault 来命名的子网。
Nginx配置
下面就是重点,nginx的配置,我的建议是一项目一个配置文件,放在容器的/etc/nginx/conf.d/下,比如两个网站,就按域名作为文件名,分别两个配置文件
下面是一个有ssl的nginx示例
# one.example.com.conf
server {
# https
listen 443 ssl;
listen [::]:443 ssl;
# 实际的域名
server_name one.example.com;
# 证书 如果你使用记得修改成实际文件路径
ssl_certificate /etc/nginx/certs/one.example.com.crt;
ssl_certificate_key /etc/nginx/certs/one.example.com.key;
location / {
# 这里就是写上docker容器地址
proxy_pass http://wordpress:80;
proxy_set_header X-Real-IP remote_addr;
proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
proxy_set_header Host host; # 这个必须加上,没有的话,会自动跳转到wordpress-one地址
proxy_set_header X-Forwarded-Protoscheme;
}
}
server {
listen 80;
listen [::]:80;
server_name one.example.com;
return 301 https://http_hostrequest_uri;
}
另一个地址的
# two.example.com.conf
server {
# https
listen 443 ssl;
listen [::]:443 ssl;
# 实际的域名
server_name two.example.com;
# 证书 如果你使用记得修改成实际文件路径
ssl_certificate /etc/nginx/certs/two.example.com.crt;
ssl_certificate_key /etc/nginx/certs/two.example.com.key;
location / {
# 这里就是写上docker容器地址
# 由于只创建了一个wordpress,所以写了同样的地址做示例,
proxy_pass http://wordpress:80;
proxy_set_header X-Real-IP remote_addr;
proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
proxy_set_header Host host; # 这个必须加上,没有的话,会自动跳转到wordpress-one地址
proxy_set_header X-Forwarded-Protoscheme;
}
}
server {
listen 80;
listen [::]:80;
server_name two.example.com;
return 301 https://http_hostrequest_uri;
}
这里说一下proxy_pass 的设置,里面的wordpress就是容器在子网里的别名,只要这个nginx容器和wordpress容器在一个子网里就能访问到,里面的proxy_set_header Host $host;则必须加上,不然会自动跳转到类似 http://子网名 这样的地址。
容器加入的子网可以使用docker inspect 容器ID查询,目前docker所有已创建的子网可以使用docker network list查询
按上面的nginx配置好后,如果你在两个nginx配置文件的proxy_pass写了不同的地址,那么访问one.example.com或者two.example.com就能访问到对应的容器
完

Comments NOTHING