question

JeromeCann-3094 avatar image
1 Vote"
JeromeCann-3094 asked ryanchill commented

Azure App Service Web SSH Error with Docker Compose (Preview) Deployment

I'm unable to SSH from the link (Kudu WebSSH) in the Azure Portal | App Service navigation pane, to a multi-container service deployed through App Service | Deployment Center | Docker Compose (Preview).

For me, everything works fine if I have specify a single container (Django) through Azure | App Service | Deployment Center. The container starts with port 2222 exposed and the SSH to the IP address works fine.

However, when using Docker Compose (Preview) with multiple containers (Gunicorn & Nginx), the SSH appears to fail because of the wrong IP address. SSH attempts to connect to an IP address that is not assigned to either Gunicorn or Nginx. It appears to be an IP address (Host) for the network that both Gunicorn and Nginx are part of, but not specific to either.




From Kudu Web SSH error message at bottom of browser:

SSH CONNECTION CLOSE - Error: connect ECONNREFUSED 172.16.117.4:2222Error: connect ECONNREFUSED 172.16.117.4:2222



From webssh log:

Host: 172.16.117.4
webssh2 Login: user=root from=127.0.0.1 host=172.16.117.4 port=2222 sessionID=undefined allowreplay=undefined
Headers: {<hidden>}
Host from file: 172.16.117.4
DEBUG: Local ident: 'SSH-2.0-ssh2js0.1.16'
on.error - Error: connect ECONNREFUSED 172.16.117.4:2222Error: connect ECONNREFUSED 172.16.117.4:2222Error: connect ECONNREFUSED 172.16.117.4:2222




From Docker Nginx log showing IP address 172.16.123.1

2021-05-11T15:16:38.065233343Z 172.16.123.1 - - [11/May/2021:15:16:38 +0000] "GET / HTTP/1.1" 301 5 "-" "AlwaysOn" "127.0.0.1:16497"




From Docker Gunicorn log showing IP address 172.16.117.3

2021-05-11T14:26:19.518533085Z [2021-05-11 14:26:19 +0000] [18] [INFO] Using worker: sync
2021-05-11T14:26:19.524015163Z [2021-05-11 14:26:19 +0000] [20] [INFO] Booting worker with pid: 20
2021-05-11T14:26:20.040158579Z Executing /home/site/wwwroot/<hidden>/settings.py ...
2021-05-11T14:26:20.040183880Z Hostname : <hidden>
2021-05-11T14:26:20.040189381Z IP : 172.16.117.3
2021-05-11T14:26:20.040193481Z platform.system() == Linux





How does Azure | App Service | SSH know which IP address on a multi-container service is the correct IP address with port 2222 exposed?


Or, how do we configure the containers to forward SSH requests from App Service Host at 172.16.117.4:2222 to Gunicorn container listening at 172.16.117.3:2222?

Do I need to add a customer network to the Docker-Compose file shown below?


version: '3.4'

services:
gunicorn:
image: <hidden>
volumes:
- static_volume:/home/site/wwwroot/<hidden>/static/
expose:
- 8000
- 2222
nginx:
image: <hidden>
volumes:
- static_volume:/home/site/wwwroot/<hidden>/static/
ports:
- <hidden>:80
depends_on:
- gunicorn

volumes:
static_volume:




Jerome

azure-webapps-ssh
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JeromeCann-3094 avatar image
0 Votes"
JeromeCann-3094 answered

After reading that only certain Docker-Compose options are supported by Azure | App Service | Deployment Center configuration, I removed the options that are supposedly ignored and SSH is now working fine with my multi-container solution

My new Docker-Compose file is below

 version: '3.4'
    
 services:
   gunicorn:
     image: <hidden>
     volumes:
       - static_volume:/home/site/wwwroot/<hidden>/static/
   nginx:
     image: <hidden>
     volumes:
       - static_volume:/home/site/wwwroot/<hidden>/static/
     ports:
       - 80
    
 volumes:
   static_volume:


Interestingly, I've read in multiple comments that only one container of a multi-container Azure App Service can communicate outside the container, but that doesn't appear to be the case when using the Docker-Compose file above.

The issue may have also been that I was previously specifying the external port to listen on, and that when I let the host assign it by only publishing port 80, everything worked fine. I'm not sure, but it's working now.



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ryanchill avatar image
0 Votes"
ryanchill answered ryanchill commented

@JeromeCann-3094,

You can enable ssh by adding the following code to your dockerfile

# Install OpenSSH and set the password for root to "Docker!". In this example, "apk add" is the install instruction for an Alpine Linux-based image.
RUN apk add openssh \
     && echo "root:Docker!" | chpasswd 

# Copy the sshd_config file to the /etc/ssh/ directory
COPY sshd_config /etc/ssh/

# Open port 2222 for SSH access
EXPOSE 80 2222

However, this will only work on your nginx since that's the container exposing port 80. You can only SSH into the main container of a multi-container setup.

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks for the response, @ryanchill

I have the code you've recommended in my Docker file. As I mentioned, SSH works fine when I deploy the app as a single Django container. It's only when I deploy the app as mutli-container (Gunicorn and Nginx) that it doesn't work, and the same SSH code exists in the Gunicorn Docker file as the Django Docker file.

Your second comment (you can only SSH into main container) is what led me to the solution. I read that same comment elsewhere and it included a link to Docker-Compose limitations when using Azure App Service, https://docs.microsoft.com/en-us/azure/app-service/configure-custom-container?pivots=container-linux.

Once I removed the Compose options that are supposedly ignored, multi-container SSH to Gunicorn worked fine. So, it seems those options are not just ignored but cause problems if included, and that you can communicate with both containers (Gunicorn and Nginx) through Azure App Service.

Jerome

1 Vote 1 ·

So for me removing the specification of the external host also solved the problem.
|
|However, when I now ssh into the container I seem to be connected to the container running my application (supervisord running gunicorn among other things) and NOT nginx as suggested by you. Why is this?

0 Votes 0 ·

Just to confirm @AnselmCoogan-2758, you have a similar docker compose and can only SSH into the gunicorn? @JeromeCann-3094, can you further elaborate on how you configured SSH on your gunicorn and nginx docker images?

0 Votes 0 ·