I have docker containers with NGINX and Docker Registry based on the tutorial at https://docs.docker.com/registry/recipes/nginx/
version: "3.5"
services:
nginx-auth:
hostname: reverse-proxy
image: nginx:alpine
restart: always
ports:
- 5044:443
links:
- registry:registry
volumes:
- ./auth:/etc/nginx/conf.d
- ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- registry-services
registry:
restart: always
image: registry:2
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
volumes:
- ./data:/var/lib/registry
networks:
- registry-services
networks:
registry-services:
external: true
When I attempt to log in using the credentials in my htpasswd file, I get an error 500
$ sudo docker login -u=testuser -p=testpassword my-docker-registry.com:5044
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: login attempt to https://my-docker-registry.com:5044/v2/ failed with status: 500 Internal Server Error
The NGINX container reports permission denied when trying to access the htpaswd file.
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
10.148.100.212 - - [03/Aug/2022:21:31:20 +0000] "GET /v2/ HTTP/1.1" 401 179 "-" "docker/19.03.6 go/go1.12.17 git-commit/369ce74a3c kernel/5.4.0-64-generic os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.6 \x5C(linux\x5C))"
2022/08/03 21:31:20 [crit] 21#21: *2 open() "/etc/nginx/conf.d/nginx.htpasswd" failed (13: Permission denied), client: 10.148.100.212, server: my-docker-registry.com, request: "GET /v2/ HTTP/1.1", host: "my-docker-registry.com:5044"
10.148.100.212 - testuser [03/Aug/2022:21:31:20 +0000] "GET /v2/ HTTP/1.1" 500 177 "-" "docker/19.03.6 go/go1.12.17 git-commit/369ce74a3c kernel/5.4.0-64-generic os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.6 \x5C(linux\x5C))"
But I can open a sh shell to the NGINX container and verify the file is there and accessible from within the container
* Executing task: docker exec -it 40412ee4cda03507e180e7dfadbbe9a060dcc90172088968a299167291a34407 sh
/ # ls -la /etc/nginx/conf.d/nginx.htpasswd
-rw-rw---- 1 675254 8000 70 Aug 3 20:57 /etc/nginx/conf.d/nginx.htpasswd
/ # cat /etc/nginx/conf.d/nginx.htpasswd
testuser:$2y$05$648qqQTyWDvUgk1G3D.o6.CG1bCYI7uu5/jqmQaWGGmEX1js4CuE6
/ #
What do I need to do to allow NGINX to read the htpasswd file?
Related
I'm using docker containers to host a web app. I have three main containers: MySQL, flask and Nginx. The first two work as expected and the latter seems to be working fine as no error is displayed in the docker-compose startup.
Nginx container initialization output:
nginx | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx | 2022/04/07 13:09:13 [notice] 1#1: using the "epoll" event method
nginx | 2022/04/07 13:09:13 [notice] 1#1: nginx/1.21.6
nginx | 2022/04/07 13:09:13 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
nginx | 2022/04/07 13:09:13 [notice] 1#1: OS: Linux 4.19.130-boot2docker
nginx | 2022/04/07 13:09:13 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
nginx | 2022/04/07 13:09:13 [notice] 1#1: start worker processes
nginx | 2022/04/07 13:09:13 [notice] 1#1: start worker process 21
Nginx dockerfile
# Dockerfile-nginx
FROM nginx:latest
# Nginx will listen on this port
# EXPOSE 80
# Remove the default config file that
# /etc/nginx/nginx.conf includes
RUN rm /etc/nginx/conf.d/default.conf
# We copy the requirements file in order to install
# Python dependencies
COPY nginx.conf /etc/nginx/conf.d/
Containers after being deployed and their respective ports:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bffffcfe2f70 sc_server_nginx "/docker-entrypoint.…" 14 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp nginx
a73d958c1407 sc_server_flask "uwsgi app.ini" 9 hours ago Up 9 hours 8080/tcp flask
d273db5f80ef mysql:5.7 "docker-entrypoint.s…" 21 hours ago Up 9 hours (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
I'm new to Nginx server, so I guess it may be a newbie error. I'm trying to redirect all the traffic from my host machine's 80 port to docker's 80 which redirects the traffic to the WSGI container via a socket.
I'm using the following Nginx configuration (nothing close to fancy I guess):
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass flask:8080;
}
}
As you can see the server listens at port 80 and redirects all the traffic via the socket uwsgi_pass flask:8080; to the WSGI container that is hosting the app.
However, whenever I type 127.0.0.1:80 or 0.0.0.0:80 in my browser the connection is refused. I have no firewall deployed, so I guess that there is no problem with port 80 being down.
This is my app.ini configuation file, in which the initialization and deployment params are indicated:
[uwsgi]
wsgi-file = wsgi.py
; This is the name of the variable
; in our script that will be called
callable = app
; We use the port 8080 which we will
; then expose on our Dockerfile
socket = :8080
; Set uWSGI to start up 4 workers
processes = 4
threads = 2
master = true
chmod-socket = 660
vacuum = true
die-on-term = true
Additionally, I also include the docker-compose.yml (I guess it may be helpful):
docker-compose.yml
services:
flask:
build: ./flask
container_name: flask
restart: always
environment:
- APP_NAME=MyFlaskApp
- YOURAPPLICATION_SETTINGS=docker_config.py
expose:
- 8080
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD:
MYSQL_DATABASE:
MYSQL_USER:
MYSQL_PASSWORD:
volumes:
- ./db/init.sql:/data/application/init.sql
healthcheck:
test: mysql -u -p --database -e "show tables;"
interval: 3s
retries: 5
start_period: 30s
nginx:
build: ./nginx
container_name: nginx
restart: always
depends_on:
- mysql
- flask
ports:
- "80:80"
Anyone can help?
Update
I've used Wireshark to scan the loopback interface to see the server's response to 0.0.0.0:80 (I suspect there might be some problem with port 80) and I get the following payload:
Update 2:
After deploying the app in EC2 everything seems to be working fine. Thus, it has to be some problem with port 80 at localhost. My machine's OS is macOS Monterrey 12.4 and the system firewall is turned down.
I have a julia app which has been dockerized using below docker file. And,I am running this local app as docker container on port 8080. The goal is to expose this docker app (port 8080) to public using nginx docker container.
I have followed this tutorial: https://www.domysee.com/blogposts/reverse-proxy-nginx-docker-compose and based on the instructions I have created two files, docker-compose.yml and nginx.conf as shown below.
Dockerfile for the local-app:
FROM julia:1.6
RUN apt-get update && apt-get install -y gcc
ENV JULIA_PROJECT #.
WORKDIR /home
ENV VERSION 1
ADD . /home
EXPOSE 8080
ENTRYPOINT ["julia", "-JApp.so", "-t", "auto", "-L", "src/App.jl", "-e", "App.run()"]
Docker-Compose:
version: "3.9"
services:
nginx:
image: nginx:alpine
container_name: production_nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- .:/usr/share/nginx/html
- ./nginx/error.log:/etc/nginx/error_log.log
- ./nginx/cache/:/etc/nginx/cache
- /etc/letsencrypt/:/etc/letsencrypt/
ports:
- 8080:80
- 443:443
local-app:
image: local-app:latest
container_name: production-local-app
expose:
- "8080"
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 app.local.hosting;
location /local-app {
proxy_pass http://localhost:8080;
rewrite ^/local-app(.*)$ $1 break;
}
listen 80;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/app.local.hosting/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.local.hosting/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
}
}
However, running the docker-compose starts two containers, 1 app and 2 nginx, but nginx exits with some error. May I ask, what could be the potential cause of the service failure. Look forward to all the suggestions, thanks in advance!
Update:
Adding the output from terminal upon executing the docker-compose file:
user#user:~/Desktop/App$sudo docker-compose up
Starting production-local-app ... done
Starting production_nginx ... done
Attaching to production_nginx, production-local-app
production_nginx | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
production_nginx | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
production_nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
production_nginx | 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
production_nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
production_nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
production_nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
production_nginx | 2021/12/05 16:27:03 [emerg] 1#1: open() "/etc/letsencrypt/options-ssl-nginx.conf" failed (2: No such file or directory) in /etc/nginx/nginx.conf:23
production_nginx | nginx: [emerg] open() "/etc/letsencrypt/options-ssl-nginx.conf" failed (2: No such file or directory) in /etc/nginx/nginx.conf:23
production_nginx exited with code 1
production-local-app |
production-local-app | Web Server starting at http://localhost:8080 - press Ctrl/Cmd+C to stop the server.
I am a bit stuck with configuring multiple services where nginx is the proxy server.
running :
docker -v
Docker version 19.03.8, build afacb8b7f0
docker-compose -v
docker-compose version 1.23.2, build 1110ad01
I want to start with this test, everything in the same docker-compose.yml-file :
link to jwilder/nginx
proxy : nginx-server (jwilder/nginx-proxy:0.7.0 , which is nginx 1.17.6)
container1 : httpd:2.4
container2 : httpd:2.4
updating my /etc/hosts before I start
127.0.0.1 container1.com
127.0.0.1 container2.com
Here is my docker-compose.yml-file (obs -> version 3.7)
version: '3.7'
services:
proxy:
image: jwilder/nginx-proxy:0.7.0
container_name: proxy-test
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx-proxy.conf:/etc/nginx/conf.d/nginx-proxy.conf:ro
container1:
image: httpd:2.4
container_name: container-1
environment:
- VIRTUAL_HOST:container1.com
ports:
- 8080:80
container2:
image: httpd:2.4
container_name: container-2
environment:
- VIRTUAL_HOST:container2.com
ports:
- 8081:80
here is my nginx-proxy.conf:
server {
listen 80;
server_name container1.com;
location / {
proxy_pass http://localhost:8080;
}
}
server {
listen 80;
server_name container2.com;
location / {
proxy_pass http://localhost:8081;
}
}
After this I run the
docker exec container-1 sed -i 's/It works!/Container 1/' /usr/local/apache2/htdocs/index.html AND docker exec container-2 sed -i 's/It works!/Container 2/' /usr/local/apache2/htdocs/index.html
Test 1 : with curl to the port 8080 and port 8081
curl localhost:8080
response -> Container 1
curl localhost:8081
response -> Container 2
Test 2 : with curl to container1.com AND container2.com
curl container1.com
status 502
curl container2.com
status 502
Are the settings in my conf wrong ?
Troubleshooting 1:
docker exec -it proxy-test bash
I can see that the nginx-proxy.conf is in the directory (/etc/nginx/conf.d)
/etc/nginx/conf.d/default.conf is there as well
Troubleshooting 2: The proxy-log (Connection refused - while connecting to upstream)
proxy-test | nginx.1 | 2020/04/03 10:52:08 [error] 61#61: *9 connect() failed (111: Connection refused) while connecting to upstream, client: 172.29.0.1, server: container1.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "container1.com"
proxy-test | nginx.1 | 2020/04/03 10:52:08 [error] 61#61: *9 connect() failed (111: Connection refused) while connecting to upstream, client: 172.29.0.1, server: container1.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "container1.com"
Found 2 solutions to this.
(1)
the first is to update the nginx-proxy.conf with the name of the containers instead of pointing to http://localhost:8080; and http://localhost:8081; :
new config-file
server {
listen 80;
server_name container1.com;
location / {
proxy_pass http://container-1;
}
}
server {
listen 80;
server_name container2.com;
location / {
proxy_pass http://container-2;
}
}
(2)
Leaving out the nginx-proxy.conf-file , docker-compose.yml will map things correctly.
Environment setup
I have an application which is composed by some services:
jenkins server
nginx server with angular
nginx server as a proxy
Those services are defined in the docker-compose file:
version: '3'
services:
reverse:
container_name: reverse-proxy
build:
context: /app/mywallet/MyWalletFe/reverse-proxy
ports:
- "80:80"
networks:
- net
jenkins:
container_name: jenkins
image: jenkins/jenkins
volumes:
- "$PWD/jenkins_home:/var/jenkins_home"
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
- net
angular:
container_name: mywallet_fe
build:
context: /app/mywallet/MyWalletFe
networks:
- net
networks:
net:
I defined the following configuration file for the reverse-proxy:
upstream client {
# angular is the name of the service in docker-compose file
server angular:4200;
}
upstream jenkins {
server jenkins:8080;
}
server {
listen 80;
location / {
proxy_pass http://client;
}
location /jenkins {
proxy_pass http://jenkins;
}
}
Finally, here is the Dockerfile for the reverse-proxy service, which copies the configuration file in the nginx container:
FROM nginx
# override default files if present
COPY ./default.conf /etc/nginx/conf.d/default.conf
Goal
My goal is to access Jenkins with SERVER_IP/jenkins
Output
When I run the whole application and try to access to SERVER_IP/jenkins, I get the following error in the reverse-proxy logs:
2020/04/15 21:44:55 [error] 6#6: *10 connect() failed (111: Connection
refused) while connecting to upstream, client: MY_CLIENT_IP, server: ,
request: "GET /login?from=%2Fjenkins HTTP/1.1", upstream:
"http://172.18.0.5:4200/login?from=%2Fjenkins", host: "SERVER_IP",
referrer: "http://SERVER_IP/jenkins" MY_CLIENT_IP
[15/Apr/2020:21:44:55 +0000] "GET /favicon.ico HTTP/1.1" 502 559
"http://SERVER_IP/login?from=%2Fjenkins" "Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" "-" 2020/04/15 21:44:55 [error]
6#6: *10 connect() failed (111: Connection refused) while connecting
to upstream, client: MY_CLIENT_IP, server: , request: "GET
/favicon.ico HTTP/1.1", upstream:
"http://172.18.0.5:4200/favicon.ico", host: "SERVER_IP",
referrer: "http://SERVER_IP/login?from=%2Fjenkins"
where MY_CLIENT_IP is my laptop IP and SERVER_IP is the IP of the server where the application runs.
What's wrong in the configuration of the reverse proxy? If I expose the jenkins and angular services I can reach them, while through the proxy I can't.
Similar question, which doesn't help me (or I don't understand how would those help me)
Docker nginx reverse proxy returns 502 bad gateway "connection refused while connecting to upstream"
Connection refused while connection to upstream - Docker
connect() failed (111: Connection refused) while connecting to upstream for nginx+php-fpm docker
docker nginx connection refused while connecting to upstream
I have the following configuration for my stack:
api:
deployment_strategy: every_node
environment:
- 'DATABASE_URL=postgresql://.....'
- REDIS_HOST=redis
image: 'image/image:latest'
links:
- redis
ports:
- '5000:5000'
lb:
image: 'dockercloud/haproxy:latest'
links:
- api
ports:
- '80:80'
privileged: true
roles:
- global
and this is the haproxy output
2017-05-26T12:00:51.752500376Z INFO:haproxy:dockercloud/haproxy 1.6.6 has access to the Docker Cloud API - will reload list of backends in real-time
2017-05-26T12:00:51.752599249Z INFO:haproxy:dockercloud/haproxy PID: 5
2017-05-26T12:00:51.883065649Z INFO:haproxy:=> Add task: Websocket open
2017-05-26T12:00:52.884078353Z INFO:haproxy:=> Executing task: Websocket open
2017-05-26T12:00:52.884105435Z INFO:haproxy:==========BEGIN==========
2017-05-26T12:00:53.364820267Z INFO:haproxy:Linked service: API(d73c0091-ae4f-43b8-a3a8-ea11a276652e)
2017-05-26T12:00:53.364872613Z INFO:haproxy:Linked container: API_1(3f981340-9b04-4105-8876-2ad1e5521f5c)
2017-05-26T12:00:53.365695674Z INFO:haproxy:HAProxy configuration:
2017-05-26T12:00:53.365705363Z global
2017-05-26T12:00:53.365708753Z log 127.0.0.1 local0
2017-05-26T12:00:53.365712075Z log 127.0.0.1 local1 notice
2017-05-26T12:00:53.365715245Z log-send-hostname
2017-05-26T12:00:53.365718228Z maxconn 4096
2017-05-26T12:00:53.365721207Z pidfile /var/run/haproxy.pid
2017-05-26T12:00:53.365724305Z user haproxy
2017-05-26T12:00:53.365727513Z group haproxy
2017-05-26T12:00:53.365730447Z daemon
2017-05-26T12:00:53.365733783Z stats socket /var/run/haproxy.stats level admin
2017-05-26T12:00:53.365736704Z ssl-default-bind-options no-sslv3
2017-05-26T12:00:53.365746260Z ssl-default-bind-ciphers xxxxxx
2017-05-26T12:00:53.365752089Z defaults
2017-05-26T12:00:53.365755064Z balance roundrobin
2017-05-26T12:00:53.365758035Z log global
2017-05-26T12:00:53.365761046Z mode http
2017-05-26T12:00:53.365764045Z option redispatch
2017-05-26T12:00:53.365767032Z option httplog
2017-05-26T12:00:53.365769951Z option dontlognull
2017-05-26T12:00:53.365775842Z option forwardfor
2017-05-26T12:00:53.365780388Z timeout connect 5000
2017-05-26T12:00:53.365793420Z timeout client 50000
2017-05-26T12:00:53.365796603Z timeout server 50000
2017-05-26T12:00:53.365799585Z listen stats
2017-05-26T12:00:53.365802356Z bind :1936
2017-05-26T12:00:53.365805270Z mode http
2017-05-26T12:00:53.365808233Z stats enable
2017-05-26T12:00:53.365811235Z timeout connect 10s
2017-05-26T12:00:53.365814235Z timeout client 1m
2017-05-26T12:00:53.365817155Z timeout server 1m
2017-05-26T12:00:53.365827005Z stats hide-version
2017-05-26T12:00:53.365830160Z stats realm Haproxy\ Statistics
2017-05-26T12:00:53.365833322Z stats uri /
2017-05-26T12:00:53.365837063Z stats auth stats:stats
2017-05-26T12:00:53.365839909Z frontend default_port_80
2017-05-26T12:00:53.365842760Z bind :80
2017-05-26T12:00:53.365845760Z reqadd X-Forwarded-Proto:\ http
2017-05-26T12:00:53.365848857Z maxconn 4096
2017-05-26T12:00:53.365851745Z default_backend default_service
2017-05-26T12:00:53.365854664Z backend default_service
2017-05-26T12:00:53.365857581Z server API_1 10.7.0.2:5000 check inter 2000 rise 2 fall 3
2017-05-26T12:00:53.365886854Z INFO:haproxy:Launching HAProxy
2017-05-26T12:00:53.368391859Z INFO:haproxy:HAProxy has been launched(PID: 12)
2017-05-26T12:00:53.368498117Z INFO:haproxy:===========END===========
when I access the haproxy IP, I get ERR_CONNECTION_REFUSED on Chrome and the API service logs is empty, but when I access the haproxy on port 5000, then yes, the request hits my API.
I found it very weird, because I thought that HAProxy would do this routing for me. Am I missing something? maybe bind 80:5000?
This very simple example is working for me:
api:
image: nginx
lb:
image: 'dockercloud/haproxy:latest'
links:
- api
ports:
- '80:80'
privileged: true
(without the roles part because I'm not using docker cloud)
...
lb_1 | INFO:haproxy:HAProxy has been launched(PID: 13)
lb_1 | INFO:haproxy:===========END===========
api_1 | 172.17.0.3 - - [26/May/2017:12:40:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" "172.17.0.1"
...
maybe bind 80:5000?
You shouldn't. It should be enough accessing :80 and then haproxy do the rest.