Docker Express App : Nginx 504 Gateway Time-out response - docker

I'm newbie in Docker and I'm following this tutorial:
Learn Docker - DevOps with Node.js & Express https://www.youtube.com/watch?v=9zUHg7xjIqQ
I'm completely stuck in the section about adding a new service, 'nginx' proxy server
My computer is a MacBook running macOS Big Sur v.11.7
Here it is the relevant code:
nginx > default.conf
server {
listen 80;
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://node-app:3000;
proxy_redirect off;
}
}
docker-compose.yml
version: "3"
services:
nginx:
image: nginx:stable-alpine
ports:
- "3000:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
node-app:
build: .
environment:
- PORT=3000
depends_on:
- mongo
mongo:
image: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=example
volumes:
- mongo-db:/data/db
redis:
image: redis
volumes:
mongo-db:
Dockerfile
FROM node:16
WORKDIR /app
COPY package.json .
ARG NODE_ENV
RUN if [ "$NODE_ENV" = "development" ]; \
then npm install; \
else npm install --only=production; \
fi
COPY . ./
ENV PORT 3000
EXPOSE $PORT
CMD ["node", "index.js"]
index.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const {
MONGO_USER,
MONGO_PW,
MONGO_PORT,
MONGO_IP,
REDIS_URL,
REDIS_PORT,
SESSION_SECRET,
} = require("./config/config");
const connectWithRetry = () => {
mongoose
.connect(
`mongodb://${MONGO_USER}:${MONGO_PW}#${MONGO_IP}:${MONGO_PORT}/?authSource=admin`
)
.then(() => console.log("Succesfully connected to DB"))
.catch((e) => {
console.log(e);
setTimeout(connectWithRetry, 5000);
});
};
connectWithRetry();
const session = require("express-session");
const redis = require("redis");
let RedisStore = require("connect-redis")(session);
let redisClient = redis.createClient({
legacyMode: true,
socket: {
port: REDIS_PORT,
host: REDIS_URL,
},
});
redisClient.connect().catch(console.error);
const sessionConfig = {
store: new RedisStore({ client: redisClient }),
secret: SESSION_SECRET,
secure: false,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
expires: Date.now + 1000 * 3600 * 24 * 7,
maxAge: 1000 * 3600 * 24 * 7,
},
};
app.use(session(sessionConfig));
app.use(express.json());
const port = process.env.PORT || 3000;
app.get("/api/v1", (req, res) => {
res.send("Home Page");
});
app.listen(port, () => {
console.log(`Serving in port: ${port}`);
});
When I place this simple request:
http://localhost:3000/api/v1/
I get this reponse from the browser:
504 Gateway Time-out
And this error message from the 'nginx' container:
2022/11/30 03:11:31 [error] 22#22: *20 upstream timed out (110: Operation timed out) while connecting to upstream, client: 192.168.0.1, server: , request: "GET /api/v1/ HTTP/1.1", upstream: "http://23.221.222.250:3000/api/v1/", host: "localhost:3000"
192.168.0.1 - - [30/Nov/2022:03:11:31 +0000] "GET /api/v1/ HTTP/1.1" 504 569 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-"`
I really appreciate any help here.

Related

Having problems to add SSL to nuxt-axios web app on DOCKER

Well after many tests and brain burns trying with nginx, caddy and other resources to apply SSL I resort to this medium.
all the services are running on docker container.
I can't fully apply the certificates, rather I can't get my site to work with SSL, I can get to the login with https but then I can't get past that barrier:
to formalize:
https://example.com:3000/login (basic web domain)
https://example.com:3001/api (all my resources)
for https i have to change the axios BASEurl form: (recomendations from caddy forum)
this: http://example.com:3001/api
to this: https://example.com/api
to stop having the error of ERR_SSL_PROTOCOL_ERROR
I share my settings from my last failed attempt with caddy.
The truth is that at this point I don't know if it is a bad configuration problem on the caddy side or on the node-nuxt-axios side.
caddyfile:
{
debug
}
example.com {
handle_path /api/* {
reverse_proxy /api/* node:3001
}
handle {
reverse_proxy node:3000
}
}
emqx.example.com {
reverse_proxy emqx:18083
}
ws.example.com {
reverse_proxy emqx:8083
}
wss.example.com {
reverse_proxy emqx:8084
}
portainer.example.com {
reverse_proxy portainer:9000
}
here it goes nuxt.config.js
axios: {
baseURL: process.env.AXIOS_BASE_URL
},
env: {
mqtt_prefix: process.env.MQTT_PREFIX,
mqtt_host: process.env.MQTT_HOST,
mqtt_port: process.env.MQTT_PORT
},
server: {
https: true,
port: 3000,
host: '0.0.0.0',
},
serverMiddleware: {
https: true,
'/api': '~/api'
},
here is the index.js for api
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
const cors = require("cors");
const colors = require("colors");
const app = express();
require("dotenv").config();
//express config
app.use(morgan("tiny"));
app.use(express.json());
app.use(express.urlencoded({
extended: true,
})
);
app.use(cors());
app.use("/api", require("./routes/devices.js"));
app.use("/api", require("./routes/users.js"));
app.use("/api", require("./routes/templates.js"));
app.use("/api", require("./routes/datas.js"));
app.use("/api", require("./routes/webhooks.js"));
app.use("/api", require("./routes/emqxapi.js"));
app.use("/api", require("./routes/alarms.js"));
app.use("/api", require("./routes/controls.js")); // nueva funcion
app.use("/api", require("./routes/dataprovider.js"));
module.exports = app;
//listener
app.listen(process.env.API_PORT, () => {
console.log("API server listening on port " + process.env.API_PORT);
}); //api port 3001
for the record all services works like a charm on http, but having problems with secure comunication.

502 Bad gateway Nginx reversy proxy, connect() failed (111: Connection refused) while connecting to upstream

I have a project, which consist of Go application + Nginx + Db(Postgres). All are building in docker containers.
It is my docker-compose.yml file:
version: "3"
services:
db:
image: postgres:10
environment:
- POSTGRES_PASSWORD=DatabasePassword
- POSTGRES_USER=egor
- POSTGRES_DB=postgres
expose:
- 5432
backend:
build: .
environment:
- POSTGRES_URL=postgres://egor:DatabasePassword#db:5432/postgres?sslmode=disable
- LISTEN_ADDRESS=:5432
depends_on:
- db
proxy:
image: nginx
volumes:
- type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
ports:
- 80:80
depends_on:
- backend
- db
it is my go application:
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/lib/pq"
"log"
"net/http"
"github.com/caarlos0/env"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
type config struct {
PostgresUri string `env:"POSTGRES_URL" envDefault:"postgres://root:pass#localhost:5432/postgres?sslmode=disable"`
ListenAddress string `env:"LISTEN_ADDRESS" envDefault:":7000"`
//PostgresHost string `env:"POSTGRES_HOST" envDefault:":l"`
//PostgresUser string `env:"POSTGRES_USER" envDefault:":root"`
//PostgresPassword string `env:"POSTGRES_PASSWD" envDefault:":qwerty"`
//PostgresName string `env:"POSTGRES_NAME" envDefault:":postgres"`
}
var (
db *sql.DB
errorsCount = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "gocalc_errors_count",
Help: "Gocalc Errors Count Per Type",
},
[]string{"type"},
)
requestsCount = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "gocalc_requests_count",
Help: "Gocalc Requests Count",
})
)
func main() {
var err error
// Initing prometheus
prometheus.MustRegister(errorsCount)
prometheus.MustRegister(requestsCount)
// Getting env
cfg := config{}
if err = env.Parse(&cfg); err != nil {
fmt.Printf("%+v\n", err)
}
time.Sleep(time.Second)
fmt.Println("Sleep over!")
// Connecting to database
//psqlInfo := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=5432 sslmode=disable",
// cfg.PostgresHost,cfg.ListenAddress,cfg.PostgresUser,cfg.PostgresPassword,cfg.PostgresName)
//db, err := sql.Open("postgres", "host=db user=egor password=DatabasePassword dbname=postgres port=5432 sslmode=disable")
db, err = sql.Open("postgres",cfg.PostgresUri)
if err != nil {
log.Fatalf("Can't connect to postgresql: %v", err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatalf("Can't ping database: %v", err)
}
http.HandleFunc("/", handler)
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(cfg.ListenAddress, nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
requestsCount.Inc()
keys, ok := r.URL.Query()["q"]
if !ok || len(keys[0]) < 1 {
errorsCount.WithLabelValues("missing").Inc()
log.Println("Url Param 'q' is missing")
http.Error(w, "Bad Request", 400)
return
}
q := keys[0]
log.Println("Got query: ", q)
var result string
sqlStatement := fmt.Sprintf("SELECT (%s)::numeric", q)
row := db.QueryRow(sqlStatement)
err := row.Scan(&result)
if err != nil {
log.Println("Error from db: %s", err)
errorsCount.WithLabelValues("db").Inc()
http.Error(w, "Internal Server Error", 500)
return
}
fmt.Fprintf(w, "query %s; result %s", q, result)
}
And my nginx configuration:
events{
worker_connections 1024;
}
http{
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend:7000;
}
}
}
But when i'm going to try page in browser, i see error page - 502 Bad Gateway nginx.
It is my log:
2022/11/08 23:41:24 [error] 29#29: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xxx.xx.x.x, server: localhost, request: "GET / HTTP/1.1", upstream: "http://xxx.xx.x.x:7000/", host: "0.0.0.0"
What is problem? All services work correctly, only nginx reversy proxy has error
I just put together a small project that represents your scenario. This is the repository structure:
webapp/
nginx/
Dockerfile
nginx.conf
web/
Dockerfile
main.go
docker-compose.yaml
The content of each file are as follows.
nginx/nginx.conf
events{}
http {
server {
listen 80;
location / {
proxy_pass http://backend:7000;
}
}
}
More or less is your same file.
nginx/Dockerfile
FROM nginx
EXPOSE 80
COPY nginx.conf /etc/nginx/nginx.conf
Here, we specify instructions to build the nginx container. We expose only the port 80.
web/main.go
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!\n")
})
http.ListenAndServe(":7000", nil)
}
Simple HTTP server with a hard-coded reply. This HTTP server listens for requests on port 7000.
web/Dockerfile
FROM golang:1.12.7-alpine3.10 AS build
WORKDIR /go/src/app
COPY ./main.go ./main.go
RUN go build -o ./bin/gowebserver ./main.go
FROM alpine:latest
COPY --from=build /go/src/app/bin /go/bin
EXPOSE 7000
ENTRYPOINT go/bin/gowebserver
Here, we use the multi-stage build. In the first section we build the HTTP server while in the second one, we copy the executable on a leaner base image of Docker. We expose port 7000 of this container.
docker-compose.yaml
version: "3"
services:
backend:
build: "./web"
expose:
- "7000"
nginx:
build: "./nginx"
ports:
- "80:80"
depends_on:
- "backend"
Here, is the last part that connects all. We expose to the outside only the port 80. Internally, the backend service exposes port 7000 to be contacted by the nginx service.
To spin up everything, you've to run these two commands (in the root folder of the project):
docker-compose build
docker-compose up
To test this solution you've to use your internal IP address (in my case was something like 192.168.1.193) and navigate to the URL http://192.168.1.193/ which should give you an Hello, World! message.
Let me know if this solves your issue!

Configure redirect Uris of Identity server in docker environment

Okay, this quite big so just skip to the last section for a brief.
I have a demo application (netcore 6.0) built on micro-service architect, suppose we have 3 services:
identity (Auth service - IdentityServer4)
frontend (mvc - aspnet)
nginx (reverse proxy server)
and all three are running on docker environment here is the docker-compose file
services:
demo-identity:
image: ${DOCKER_REGISTRY-}demoidentity:lastest
build:
context: .
dockerfile: Identity/Demo.Identity/Dockerfile
ports:
- 5000:80 //only export port 80,
volumes:
- ./Identity/Demo.Identity/Certificate:/app/Certificate:ro
networks:
- internal
demo-frontend:
image: ${DOCKER_REGISTRY-}demofrontend:lastest
build:
context: .
dockerfile: Frontend/Demo.Frontend/Dockerfile
ports:
- 5004:80 //only export port 80,
networks:
- internal
proxy:
build:
context: ./nginx-reverse-proxy
dockerfile: Dockerfile
ports:
- 80:80
- 443:443
volumes:
- ./nginx-reverse-proxy/cert/:/etc/cert/
links:
- demo-identity
depends_on:
- demo-identity
- demo-frontend
networks:
- internal
They all design to run internal, but nginx, it will be the proxy server, and here is the nginx.config file
worker_processes 4;
events { worker_connections 1024; }
http {
upstream app_servers_identity {
server demo-identity:80;
}
upstream app_servers_frontend {
server demo-frontend:80;
}
server {
listen 80;
listen [::]:80;
server_name demo-identity;
return 301 https://identity.demo.local$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name identity.demo.local;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name identity.demo.local;
ssl_certificate /etc/cert/demo.crt;
ssl_certificate_key /etc/cert/demo.key;
location / {
proxy_pass http://app_servers_identity;
proxy_redirect off;
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-Host $server_name;
}
}
server {
listen 80;
listen [::]:80;
server_name frontend.demo.local;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name frontend.demo.local;
ssl_certificate /etc/cert/demo.crt;
ssl_certificate_key /etc/cert/demo.key;
location / {
proxy_pass http://app_servers_frontend;
proxy_redirect off;
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-Host $server_name;
}
}
}
also I update the host file to configure two virtual hosts identity.demo.local and frontend.demo.local (the term "localhost" sometimes confusing me when using docker.)
Then I setup the identity server like this
...
builder.Services.Configure<IdentityOptions>(options => {
// Default Password settings.
});
services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddAspNetIdentity<ApplicationUser>()
.AddSigningCredential(new X509Certificate2("./Certificate/demo_dev.pfx", "******"));
...
and here is the client static config
...
new Client
{
ClientName = "MVC Client",
ClientId = "mvc-client",
AllowedGrantTypes = GrantTypes.Hybrid,
RedirectUris = new List<string>{ "http://gateway.demo.local/signin-oidc"},
RequirePkce = false,
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile },
ClientSecrets = { new Secret("MVCSecret".Sha512()) }
}
...
In the Frontend service, I also configure Oidc as below
...
services.AddAuthentication(opt =>
{
opt.DefaultScheme = "Cookies";
opt.DefaultChallengeScheme = "oidc";
}).AddCookie("Cookies", opt => {
opt.CookieManager = new ChunkingCookieManager();
opt.Cookie.HttpOnly = true;
opt.Cookie.SameSite = SameSiteMode.None;
opt.Cookie.SecurePolicy = CookieSecurePolicy.Always;
})
.AddOpenIdConnect("oidc", opt => {
opt.SignInScheme = "Cookies";
opt.Authority = "http://demo-identity";
opt.ClientId = "mvc-client";
opt.ResponseType = "code id_token";
opt.SaveTokens = true;
opt.ClientSecret = "MVCSecret";
opt.ClaimsIssuer = "https://identity.demo.local";
opt.RequireHttpsMetadata = false;
});
...
TL,DR: A micro-service application host on docker, which included IdentityServer, MVC, Nginx. They all run internal and only can be access via nginx proxy. The host name also configure to virtual host names - which make more sense.
Okay here is the problem, when I access to a protected api of MVC, it redirect me to identity server (identity.demo.local) to login, but after I login success, it should redirect me to the mvc, but it did not. After research, I figure out the reason that after login, the identity redirect me to the origin site with the cookies contain authentication info, but the redirect uri is not secured, it's http://frontend.demo.local instead of https. I'm not sure how this property is configured ( I try to update the nginx.conf but nothing change). And it still work correctly when I run by visual studio, without docker.
Any help is appreciated.

How to connect go grpc server with dart grpc client using Envoy and Grpc_web

I'm new to grpc_web and envoy.
Please help me to setup following things,
GRPC_Go server is running on ec2 instance as a docker container
Dart web client is running on local pc
Need to make grpc call request from dart web app to grpc_go server
Used envoy proxy for the request forward. Envoy proxy is running as a container in same ec2 instance
I'm getting the following error "Response: null, trailers: {access-control-allow-credentials: true, access-control-allow-origin: http://127.0.0.1:9000, vary: Origin})".
Grpc_Go:
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
var (
port = flag.Int("port", 50051, "The server port")
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply,
error)
{
return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil
}
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
GRPC_dart_client:
import 'package:grpc/grpc_web.dart';
import 'package:grpc_web/app.dart';
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
void main() {
final channel = GrpcWebClientChannel.xhr(Uri.parse('http://ec2-ip:8080'));
final service = EchoServiceClient(channel);
final app = EchoApp(service);
final button = querySelector('#send') as ButtonElement;
button.onClick.listen((e) async {
final msg = querySelector('#msg') as TextInputElement;
final value = msg.value!.trim();
msg.value = '';
if (value.isEmpty) return;
if (value.indexOf(' ') > 0) {
final countStr = value.substring(0, value.indexOf(' '));
final count = int.tryParse(countStr);
if (count != null) {
app.repeatEcho(value.substring(value.indexOf(' ') + 1), count);
} else {
app.echo(value);
}
} else {
app.echo(value);
}
});
}
envoy.yaml:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: echo_service
timeout: 0s
max_stream_duration:
grpc_timeout_header_max: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.cors
- name: envoy.filters.http.router
clusters:
- name: echo_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: app
port_value: 50051
Grpc_go_docker_file:
# Install git.
# Git is required for fetching the dependencies.
RUN apk update && apk add --no-cache git
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Start a new stage from scratch
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copy the Pre-built binary file from the previous stage. Observe we also copied the .env file
COPY --from=builder /app/main .
# Expose port 50051 to the outside world
EXPOSE 50051
CMD ["./main"]
Envoy_Docker:
COPY envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml -l trace --log-path /tmp/envoy_info.log
I'm stuck with it more than two days, please help me. Thanks in advance
Thank you all, for your reply.
I fixed this issue with IP of the ec2 instance.
clusters:
- name: echo_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: app
port_value: 50051
Instead of container 'address: app' (app is container name) in the envoy.yaml, I used the ip of ec2 instance and container port now envoy is forwarding the request to server.

Nginx docker compose - volume add nginx.conf (reverse proxy)

I want to containerize my web applications. Currently, I am using Apache to provide a couple of PHP apps.
Every app should be provided by their own container.
Nginx should be reachable by port 80/443. Depending on the sub route it should proxying to one of the containers.
For example:
www.url.de/hello1 --> hello1:80
www.url.de/hello2 --> hello2:80
docker-compose.yml:
version: '3'
services:
nginx:
image: nginx:latest
container_name: reverse_proxy
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
- "443:443"
networks:
- app-network
depends_on:
- hello1
- hello2
hello1:
build: ./test1
image: hello1
container_name: hello1
expose:
- "80"
networks:
- app-network
hello2:
build: ./test2
image: hello2
container_name: hello2
expose:
- "80"
networks:
- app-network
networks:
app-network:
nginx.conf:
events {
}
http {
error_log /etc/nginx/error_log.log warn;
client_max_body_size 20m;
proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;
server {
server_name wudio.de;
location / {
proxy_pass http://hello1:80;
}
location /hello1/ {
proxy_pass http://hello1:80;
rewrite ^/hello1(.*)$ $1 break;
}
location /hello2/ {
proxy_pass http://hello2:80;
rewrite ^/hello2(.*)$ $1 break;
}
}
}
If I run docker-compose up -d, only the container with image webapp-test1 is online. And I also can reach it by curl localhost:8081.
Nginx is not running. If I remove the line in which I add nginx.conf to the volume of Nginx, it´s working.
What I´m doing wrong?
Edit1:
http:// was missing. But proxying still not working on subroutes. Only location / is working. How I get /hell1 running?
Note the proxy_pass statement. You have to mention the protocol in that statement. Also note how you can refer to the name of the service in your docker-compose.yml file (in this case hello1).
events {
}
http {
error_log /etc/nginx/error_log.log warn;
client_max_body_size 20m;
proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;
server {
listen 80;
location / {
try_files $uri #proxy ;
}
location #proxy {
proxy_pass http://hello1:80/;
}
}
}
Edit: Try this instead
events {
}
http {
error_log /etc/nginx/error_log.log warn;
client_max_body_size 20m;
proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;
server {
listen 80;
location / {
try_files $uri #proxy ;
}
location #proxy {
if ($request_uri ~* "^\/hello1(\/.*)$") {
set $url "http://hello1:80$1";
}
if ($request_uri ~* "^\/hello2(\/.*)$") {
set $url "http://hello2:80$1";
}
proxy_pass "$url"
}
}
}

Resources