Docker-与 nginx 反向组合,一个网站和一个 restful api?
Docker-compose with nginx reverse, a website and a restful api?
希望你能帮我解决我的问题!这是信息。
情况
我目前有两个工作容器,我需要在同一个端口 80 上 运行。有一个网站,目前只需转到服务器的主机 url 即可访问,和 restful api。但是,它必须通过端口 80 来工作,并且登录向 restful api 发出请求,后者也必须侦听端口 80 才能处理请求。因此,据我所知,我需要一个反向代理(例如 nginx)来适当地映射 interl/external 端口。
问题
关于 docker 将 nginx 反向代理与其他两个容器一起使用的教程,我真的不明白...目前,restful api使用简单的 Docker 文件,应用程序使用 docker-compose 和 mysql 数据库。我很不确定我应该怎么做。我是否应该将所有这些都放在一个带有 nginx 反向代理的文件夹中,然后 docker-compose 处理所有具有 dockerfiles/docker-compose 的子文件夹?我看到的大多数教程都谈论拥有两个不同的网站等,但似乎没有多少人谈论 restful api 以及它的网站。据我了解,我肯定会使用 this docker hub image.
Docker 图片当前结构
- RestApi
- Dockerfile
- main.go
- Website
- Dockerfile
- Docker-compose
- Ruby app
我是否应该沿着反向代理文件夹创建一个父文件夹并将所有这 3 个放在父文件夹中?像 :
- Parentfolder
- Reverse-proxy
- RestApi
- Website
然后有些网站在谈论修改启用站点的文件夹,有些没有,有些谈论 vritual-hosts,其他人谈论用网络标签启动 docker...我应该放在哪里我的nginx.conf?我想在反向代理文件夹中并安装它,但我不确定。老实说,我有点失落!下面是我现在的dockerfile/docker-composes.
RestApi Docker文件
FROM golang:1.14.4-alpine3.12
WORKDIR /go/src/go-restapi/
COPY ./testpackage testpackage/
COPY ./RestAPI .
RUN apk update
RUN apk add git
RUN go get -u github.com/dgrijalva/jwt-go
RUN go get -u github.com/go-sql-driver/mysql
RUN go get -u github.com/gorilla/context
RUN go get -u github.com/gorilla/mux
RUN go build -o main .
EXPOSE 12345
CMD ["./main"]
网站Docker文件
FROM ruby:2.7.1
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y bash nodejs tzdata netcat libpq-dev nano tzdata apt-transport-https yarn
RUN gem install bundler
RUN mkdir /myapp
WORKDIR /myapp
COPY package.json yarn.lock Gemfile* ./
RUN yarn install --check-files
RUN bundle install
COPY . .
# EXPOSE 3000
# Running the startup script before starting the server
ENTRYPOINT ["sh", "./config/docker/startup.sh"]
CMD ["rails", "server", "-b", "-p 3000" "0.0.0.0"]
网站Docker-撰写
version: '3'
services:
db:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
# volumes:
# - ./tmp/db:/var/lib/postgresql/data
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_dev
MYSQL_USERNAME: root
MYSQL_PASSWORD: root
web:
build: .
# command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# volumes:
# - .:/myapp
ports:
- "80:3000"
depends_on:
- db
links:
- db
environment:
DB_USER: root
DB_NAME: test_dev
DB_PASSWORD: root
DB_HOST: db
DB_PORT: 3306
RAILS_ENV: development
我是否应该只希望“docker-合成”一张图像,然后用反向代理处理另外两张图像?如果有人能指出他们认为可以很好地解决我的问题的方法,我将不胜感激!任何被视为有帮助的教程也将不胜感激!我在 google 上看得最多,他们似乎都跳过了一些步骤,但我对此很陌生,这有点困难...
非常感谢!
新 docker-compose.yml
version: '3.5'
services:
frontend:
image: 'test/webtest:first-test'
depends_on:
- db
environment:
DB_USER: root
DB_NAME: test_dev
DB_PASSWORD: root
DB_HOST: db
DB_PORT: 3306
RAILS_ENV: development
ports:
- "3000:3000"
networks:
my-network-name:
aliases:
- frontend-name
backend:
depends_on:
- db
image: 'test/apitest:first-test'
ports:
- "12345:12345"
networks:
my-network-name:
aliases:
- backend-name
nginx-proxy:
depends_on:
- frontend
- backend
image: nginx:alpine
volumes:
- $PWD/default.conf:/etc/nginx/conf.d/default.conf
networks:
my-network-name:
aliases:
- proxy-name
ports:
- 80:80
- 443:443
db:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_dev
MYSQL_USERNAME: root
MYSQL_PASSWORD: root
ports:
- '3306:3306'
networks:
my-network-name:
aliases:
- mysql-name
networks:
my-network-name:
我专门写了一篇关于使用 nginx 和 docker 的反向代理的教程。
Create An Nginx Reverse Proxy With Docker
你基本上有 3 个容器和两个没有暴露的端口,它们将通过 docker 网络进行通信并且每个都连接到网络。
Bash 方法:
docker create my-network;
# docker run -it -p 80:80 --network=my-network ...
或
Docker 编写方法:
文件: docker-compose.yml
version: '3'
services:
backend:
networks:
- my-network
...
frontend:
networks:
- my-network
proxy:
networks:
- my-network
networks:
my-network:
- A - Nginx 容器代理 - MAPPED 80/80
- B - REST API - 内部服务 80 - 给定名称
backend
- C - 网站 - 内部服务 80 - 给定名称
frontend
在容器 A 中,您将只有一个 nginx conf 文件,它通过特定路由指向不同的服务:
文件: /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://frontend;
}
location /api {
proxy_pass http://backend:5000/;
}
//...
}
这使得当您访问时:
如果您有任何问题,请告诉我,我已经构建了几次,甚至还向代理容器添加了 SSL。
如果您要为本地开发测试一项服务,这很好,但对于生产(取决于您的托管服务提供商),情况就不同了,他们可能会使用自己的代理和负载均衡器自行管理.
=====================更新 1:================ =====
这是为了在 docker compose 中模拟后端、前端、代理和 mysql 容器。
主项目目录中需要四个文件才能正常工作。
文件:
- backend.html
- frontend.html
- default.conf
- docker-compose.yml
文件: ./backend.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Backend API</title>
</head>
<body>
<h1>Backend API</h1>
</body>
</html>
文件: ./frontend.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend / Website</title>
</head>
<body>
<h1>Frontend / Website</h1>
</body>
</html>
配置代理 nginx 以指向网络上正确的容器。
文件: ./default.conf
# This is a default site configuration which will simply return 404, preventing
# chance access to any other virtualhost.
server {
listen 80 default_server;
listen [::]:80 default_server;
# Frontend
location / {
proxy_pass http://frontend-name; # same name as network alias
}
# Backend
location /api {
proxy_pass http://backend-name/; # <--- note this has an extra /
}
# You may need this to prevent return 404 recursion.
location = /404.html {
internal;
}
}
文件: ./docker-compose.yml
version: '3.5'
services:
frontend:
image: nginx:alpine
volumes:
- $PWD/frontend.html:/usr/share/nginx/html/index.html
networks:
my-network-name:
aliases:
- frontend-name
backend:
depends_on:
- mysql-database
image: nginx:alpine
volumes:
- $PWD/backend.html:/usr/share/nginx/html/index.html
networks:
my-network-name:
aliases:
- backend-name
nginx-proxy:
depends_on:
- frontend
- backend
image: nginx:alpine
volumes:
- $PWD/default.conf:/etc/nginx/conf.d/default.conf
networks:
my-network-name:
aliases:
- proxy-name
ports:
- 1234:80
mysql-database:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_DATABASE: 'root'
MYSQL_ROOT_PASSWORD: 'secret'
ports:
- '3306:3306'
networks:
my-network-name:
aliases:
- mysql-name
networks:
my-network-name:
创建这些文件然后 运行:
docker-compose -d up;
然后访问:
- 前端 - http://localhost:1234
- 后端 - http://localhost:1234/api
您会看到这两条路线现在都与各自的服务通信。
您还可以看到前端和后端没有暴露的端口。
那是因为它们中的 nginx 默认端口 80,我们在我们的网络中给它们别名 my-network-name)
来引用它们。
另外,我添加了一个 mysql 容器,它确实有暴露的端口,但你不能暴露它们,只能让后端与主机通信:端口 3306
上的 mysql-name
。
如果您在进入 docker-compose 之前进一步了解该过程以了解其工作原理,我真的建议您查看上面 link 中的教程。
希望对您有所帮助。
=====================更新 2:================ =====
这是一张图表:
希望你能帮我解决我的问题!这是信息。
情况
我目前有两个工作容器,我需要在同一个端口 80 上 运行。有一个网站,目前只需转到服务器的主机 url 即可访问,和 restful api。但是,它必须通过端口 80 来工作,并且登录向 restful api 发出请求,后者也必须侦听端口 80 才能处理请求。因此,据我所知,我需要一个反向代理(例如 nginx)来适当地映射 interl/external 端口。
问题
关于 docker 将 nginx 反向代理与其他两个容器一起使用的教程,我真的不明白...目前,restful api使用简单的 Docker 文件,应用程序使用 docker-compose 和 mysql 数据库。我很不确定我应该怎么做。我是否应该将所有这些都放在一个带有 nginx 反向代理的文件夹中,然后 docker-compose 处理所有具有 dockerfiles/docker-compose 的子文件夹?我看到的大多数教程都谈论拥有两个不同的网站等,但似乎没有多少人谈论 restful api 以及它的网站。据我了解,我肯定会使用 this docker hub image.
Docker 图片当前结构
- RestApi
- Dockerfile
- main.go
- Website
- Dockerfile
- Docker-compose
- Ruby app
我是否应该沿着反向代理文件夹创建一个父文件夹并将所有这 3 个放在父文件夹中?像 :
- Parentfolder
- Reverse-proxy
- RestApi
- Website
然后有些网站在谈论修改启用站点的文件夹,有些没有,有些谈论 vritual-hosts,其他人谈论用网络标签启动 docker...我应该放在哪里我的nginx.conf?我想在反向代理文件夹中并安装它,但我不确定。老实说,我有点失落!下面是我现在的dockerfile/docker-composes.
RestApi Docker文件
FROM golang:1.14.4-alpine3.12
WORKDIR /go/src/go-restapi/
COPY ./testpackage testpackage/
COPY ./RestAPI .
RUN apk update
RUN apk add git
RUN go get -u github.com/dgrijalva/jwt-go
RUN go get -u github.com/go-sql-driver/mysql
RUN go get -u github.com/gorilla/context
RUN go get -u github.com/gorilla/mux
RUN go build -o main .
EXPOSE 12345
CMD ["./main"]
网站Docker文件
FROM ruby:2.7.1
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y bash nodejs tzdata netcat libpq-dev nano tzdata apt-transport-https yarn
RUN gem install bundler
RUN mkdir /myapp
WORKDIR /myapp
COPY package.json yarn.lock Gemfile* ./
RUN yarn install --check-files
RUN bundle install
COPY . .
# EXPOSE 3000
# Running the startup script before starting the server
ENTRYPOINT ["sh", "./config/docker/startup.sh"]
CMD ["rails", "server", "-b", "-p 3000" "0.0.0.0"]
网站Docker-撰写
version: '3'
services:
db:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
# volumes:
# - ./tmp/db:/var/lib/postgresql/data
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_dev
MYSQL_USERNAME: root
MYSQL_PASSWORD: root
web:
build: .
# command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# volumes:
# - .:/myapp
ports:
- "80:3000"
depends_on:
- db
links:
- db
environment:
DB_USER: root
DB_NAME: test_dev
DB_PASSWORD: root
DB_HOST: db
DB_PORT: 3306
RAILS_ENV: development
我是否应该只希望“docker-合成”一张图像,然后用反向代理处理另外两张图像?如果有人能指出他们认为可以很好地解决我的问题的方法,我将不胜感激!任何被视为有帮助的教程也将不胜感激!我在 google 上看得最多,他们似乎都跳过了一些步骤,但我对此很陌生,这有点困难...
非常感谢!
新 docker-compose.yml
version: '3.5'
services:
frontend:
image: 'test/webtest:first-test'
depends_on:
- db
environment:
DB_USER: root
DB_NAME: test_dev
DB_PASSWORD: root
DB_HOST: db
DB_PORT: 3306
RAILS_ENV: development
ports:
- "3000:3000"
networks:
my-network-name:
aliases:
- frontend-name
backend:
depends_on:
- db
image: 'test/apitest:first-test'
ports:
- "12345:12345"
networks:
my-network-name:
aliases:
- backend-name
nginx-proxy:
depends_on:
- frontend
- backend
image: nginx:alpine
volumes:
- $PWD/default.conf:/etc/nginx/conf.d/default.conf
networks:
my-network-name:
aliases:
- proxy-name
ports:
- 80:80
- 443:443
db:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_dev
MYSQL_USERNAME: root
MYSQL_PASSWORD: root
ports:
- '3306:3306'
networks:
my-network-name:
aliases:
- mysql-name
networks:
my-network-name:
我专门写了一篇关于使用 nginx 和 docker 的反向代理的教程。
Create An Nginx Reverse Proxy With Docker
你基本上有 3 个容器和两个没有暴露的端口,它们将通过 docker 网络进行通信并且每个都连接到网络。
Bash 方法:
docker create my-network;
# docker run -it -p 80:80 --network=my-network ...
或
Docker 编写方法:
文件: docker-compose.yml
version: '3'
services:
backend:
networks:
- my-network
...
frontend:
networks:
- my-network
proxy:
networks:
- my-network
networks:
my-network:
- A - Nginx 容器代理 - MAPPED 80/80
- B - REST API - 内部服务 80 - 给定名称
backend
- C - 网站 - 内部服务 80 - 给定名称
frontend
在容器 A 中,您将只有一个 nginx conf 文件,它通过特定路由指向不同的服务:
文件: /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://frontend;
}
location /api {
proxy_pass http://backend:5000/;
}
//...
}
这使得当您访问时:
如果您有任何问题,请告诉我,我已经构建了几次,甚至还向代理容器添加了 SSL。
如果您要为本地开发测试一项服务,这很好,但对于生产(取决于您的托管服务提供商),情况就不同了,他们可能会使用自己的代理和负载均衡器自行管理.
=====================更新 1:================ =====
这是为了在 docker compose 中模拟后端、前端、代理和 mysql 容器。
主项目目录中需要四个文件才能正常工作。
文件:
- backend.html
- frontend.html
- default.conf
- docker-compose.yml
文件: ./backend.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Backend API</title>
</head>
<body>
<h1>Backend API</h1>
</body>
</html>
文件: ./frontend.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend / Website</title>
</head>
<body>
<h1>Frontend / Website</h1>
</body>
</html>
配置代理 nginx 以指向网络上正确的容器。
文件: ./default.conf
# This is a default site configuration which will simply return 404, preventing
# chance access to any other virtualhost.
server {
listen 80 default_server;
listen [::]:80 default_server;
# Frontend
location / {
proxy_pass http://frontend-name; # same name as network alias
}
# Backend
location /api {
proxy_pass http://backend-name/; # <--- note this has an extra /
}
# You may need this to prevent return 404 recursion.
location = /404.html {
internal;
}
}
文件: ./docker-compose.yml
version: '3.5'
services:
frontend:
image: nginx:alpine
volumes:
- $PWD/frontend.html:/usr/share/nginx/html/index.html
networks:
my-network-name:
aliases:
- frontend-name
backend:
depends_on:
- mysql-database
image: nginx:alpine
volumes:
- $PWD/backend.html:/usr/share/nginx/html/index.html
networks:
my-network-name:
aliases:
- backend-name
nginx-proxy:
depends_on:
- frontend
- backend
image: nginx:alpine
volumes:
- $PWD/default.conf:/etc/nginx/conf.d/default.conf
networks:
my-network-name:
aliases:
- proxy-name
ports:
- 1234:80
mysql-database:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_DATABASE: 'root'
MYSQL_ROOT_PASSWORD: 'secret'
ports:
- '3306:3306'
networks:
my-network-name:
aliases:
- mysql-name
networks:
my-network-name:
创建这些文件然后 运行:
docker-compose -d up;
然后访问:
- 前端 - http://localhost:1234
- 后端 - http://localhost:1234/api
您会看到这两条路线现在都与各自的服务通信。
您还可以看到前端和后端没有暴露的端口。
那是因为它们中的 nginx 默认端口 80,我们在我们的网络中给它们别名 my-network-name)
来引用它们。
另外,我添加了一个 mysql 容器,它确实有暴露的端口,但你不能暴露它们,只能让后端与主机通信:端口 3306
上的 mysql-name
。
如果您在进入 docker-compose 之前进一步了解该过程以了解其工作原理,我真的建议您查看上面 link 中的教程。
希望对您有所帮助。
=====================更新 2:================ =====
这是一张图表: