Running shinyproxy inside a docker container


#1

Hi,

yes my question looks like tricky… but not really :smiley:

Does someone manage to run shinyproxy inside a docker container ?

This is the Dockerfile a made :

FROM openjdk
RUN apt-get update
RUN apt-get -y install nano htop
VOLUME "/home/shiny"
RUN apt-get -y  install \
 apt-transport-https \
 ca-certificates \
 curl \
 gnupg2 \
 software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
RUN apt-get update
RUN apt-get install -y docker-ce
VOLUME /var/lib/docker
CMD ["java","-jar","/home/shiny/shinyproxy.jar"]

I can build this image using

docker build -t shinyproxy .

And I can run this :

docker run -p 8080:8080 --privileged -v /home/shiny:/home/shiny -v /var/run/docker.sock:/var/run/docker.sock -it shinyproxy

(of course shinyproxy.jar have to be in /home/shiny on the host machine)

Shinyproxy is online at my_ip:8080 , ask for credentiel (tesla//password), but cant run any app.

I have this error :

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is eu.openanalytics.ShinyProxyException: Failed to start container: java.util.concurrent.ExecutionException: javax.ws.rs.ProcessingException: org.apache.http.conn.HttpHostConnectException: Connect to localhost:2375 [localhost/127.0.0.1] failed: Connection refused (Connection refused)

I dont know how to deal with the :
ExecStart=/usr/bin/docker daemon -H fd:// -D -H tcp://127.0.0.1:2375

Any Idea ?

Regards


#2

It requires a service inside of a container to access the docker daemon on host. Not sure if is doable…


#3

Hi,

You don’t need to install the docker daemon in your shinyproxy docker image because you will call the docker daemon on the actual host so be able to spawn containers at the runtime. To do that, you will need to specify --net=host when starting the container so it will share the network with the host machine thus it will be able to invoke the docker daemon.

I’m using a very simple Dockerfile like this:

FROM java:8

WORKDIR usr/app/shinyproxy

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "shinyproxy-0.9.4.jar"]

I put the shinyproxy jar file on the host under directory /home/myname/shinyproxy. You can also place the application.yml in the same folder too.

Then I started the container by

docker run --net=host --restart=unless-stopped -d -v /home/myname/shinyproxy:/usr/app/shinyproxy local/shinyproxy

-d switch is to run this docker container detached.

local/shinyproxy is the name you specify when you build the image from the Dockerfile ‘docker build --rm -t local/shinyproxy .’


Running ShinyProxy in Kubernetes
#4

thks i will try this.

Regards


#5

So,

I tried but I have this error:

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-30 19:02:07.687 ERROR 1 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

But 8080 is free on host :

root@ns345323:/home/shiny/container# netstat -lt
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat
tcp        0      0 localhost:domain        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:953           0.0.0.0:*               LISTEN
tcp        0      0 localhost:2375          0.0.0.0:*               LISTEN
tcp6       0      0 [::]:http-alt           [::]:*                  LISTEN
tcp6       0      0 [::]:http               [::]:*                  LISTEN
tcp6       0      0 [::]:10001              [::]:*                  LISTEN
tcp6       0      0 [::]:8082               [::]:*                  LISTEN
tcp6       0      0 [::]:8787               [::]:*                  LISTEN
tcp6       0      0 localhost:domain        [::]:*                  LISTEN
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN
tcp6       0      0 [::]:smtp               [::]:*                  LISTEN
tcp6       0      0 localhost:953           [::]:*                  LISTEN
tcp6       0      0 [::]:https              [::]:*                  LISTEN
tcp6       0      0 [::]:8000               [::]:*                  LISTEN
tcp6       0      0 [::]:32705              [::]:*                  LISTEN
tcp6       0      0 [::]:12001              [::]:*                  LISTEN
tcp6       0      0 [::]:imaps              [::]:*                  LISTEN
tcp6       0      0 [::]:3939               [::]:*                  LISTEN
tcp6       0      0 [::]:32805              [::]:*                  LISTEN
tcp6       0      0 [::]:submission         [::]:*                  LISTEN
tcp6       0      0 [::]:imap2              [::]:*                  LISTEN

I tried all this configuration with same error :

docker run --net=host -v /home/shiny/:/usr/app/shinyproxy   --privileged -p 8080:8080 shinyproxy
docker run --net=host -v /home/shiny/:/usr/app/shinyproxy   --privileged shinyproxy
docker run --net=host -v /home/shiny/:/usr/app/shinyproxy   -p 8080:8080 shinyproxy
docker run --net=host -v /home/shiny/:/usr/app/shinyproxy   shinyproxy

Do I miss something ?


#6

I’m guessing the mistake is your previous docker container is using the port 8080 already. (shinyproxy starts at port 8080 by default).

can you try docker ps to see if the container you made in the first place is still running?

Also, I updated my last reply and you can use the new command. You don’t need to specify for port mapping by -p anymore when you are using net=host option. Have you re-run the docker build command? since I noticed you are still using the same name ‘shinyproxy’ for the docker image you are using. What about building it as something else like ‘local/shinyproxy’


#7

I was obliged to add

ExecStart=/usr/bin/dockerd -H fd:// -D -H tcp://127.0.0.1:2375

in the host.
now, it’s fork perfectly (without breaking the other containers)

Now, i would like to use docker-compose like this :

shinyproxy:
  restart: always
  build: container
  #image: local/shinyproxy
  network_mode: "host"

  volumes:
    - /home/shiny/:/usr/app/shinyproxy

but i think that there is issue with --net:host .

ERROR: The Compose file ‘./docker-compose.yml’ is invalid because:
Unsupported config option for shinyproxy: ‘network_mode’

But it’s not a shinyproxy issue. I will find a way.

thanks a lot for your help !

Regards


#8

this docker-compose.yml is ok :slight_smile:

shinyproxy:
  restart: always
  build: container
  #image: local/shinyproxy
  net: "host"

  volumes:
    - /home/shiny/:/usr/app/shinyproxy

#9

@Keqiang_Li Didn’t know it can be done like this. Thanks for sharing.


#10

Can you explain why you want to use docker compose? This is just out of curiosity because I’ve never used it before. Thanks


#11

because I use rancher http://rancher.com/

and because i like doing this :

nginx-proxy:
    restart: always
    image: jwilder/nginx-proxy
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - /srv/docker/nginx/certs:/etc/nginx/certs:ro
        - /etc/nginx/vhost.d
        - /usr/share/nginx/html
        - /var/run/docker.sock:/tmp/docker.sock:ro

nginx-proxy-companion:
    restart: always
    image: jrcs/letsencrypt-nginx-proxy-companion
    volumes:
        - /srv/docker/nginx/certs:/etc/nginx/certs:rw
        - /var/run/docker.sock:/var/run/docker.sock
    volumes_from:
        - nginx-proxy

and run multiple docker with a simple docker-compose up


#12

@VincentGuyader Could you explain how/where you added:

ExecStart=/usr/bin/dockerd -H fd:// -D -H tcp://127.0.0.1:2375

Did you somehow incorporate it into your Dockerfile, or was this a command you ran on your host machine?

Thanks for any help!


#13

Hi @Ben_Gready

That’s a command you use to configure your docker host. See docker startup options on https://www.shinyproxy.io/getting-started/ since the command varies when you have different linux distributions.


#14

Hi @Keqiang_Li - many thanks for the reply - I should have read the intro page more carefully! It is now working for me.


#15

Hi Ben, can I ask if you could share like a github link where you have your final setup. I am trying the same thing but with a docker-compose version three. I am struggling to get the container running shinyproxy to interact with the docker daemon. I did add the ExecStart in the docker service and restarted docker as in the getting started.


#16

Hi @gbisschoff, @Keqiang_Li, @Ben_Gready, @VincentGuyader,

FYI ShinyProxy 1.1.0 has official support now for being run inside a Docker container. There are explanations on https://www.shinyproxy.io/shinyproxy-containers/ and examples for running ShinyProxy containerized both with Docker Engine and Kubernetes on Github.

The new version (and release notes) can be found on https://www.shinyproxy.io/downloads/

Hope this helps!

Best,
Tobias


#17

Hi,

I have the following setup:
two simple apps, one with authorization (port 8082), another without (port 8085);
nginx;
two shinyproxies for two respective apps on respective ports.

The attempt to have it all dockerized with docker-compose was so far unsuccessful.

My docker-compose.yml:

version: '3'

services:
  shinyproxy1:
    build:  /home/admin/sp1
    container_name: shinyproxy1
    restart: on-failure
    ports:
        - 8082:8082
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock
    networks:
      app_net:
        
    
  shinyproxy2:
    build:  /home/admin/sp2
    container_name: shinyproxy2
    restart: on-failure  
    ports:
        - 8085:8085
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock
    networks:
      app_net:
    
  euler:
    build: /home/admin/shiny/euler
    container_name: euler
    restart: on-failure
    networks:
      app_net:
        ipv4_address: 172.16.238.30
        
  test_app1:
    build: /home/admin/shiny/test_app1
    container_name: test_app1
    restart: on-failure     
    networks:
      app_net:
        ipv4_address: 172.16.238.33
  
  
  nginx:
    build: /home/admin/nginx
    container_name: nginx
    restart: always
    command: service nginx start
    ports:
        - 80:80
        - 443:443
    links:
        - euler
        - test_app1
    networks:
      app_net:
        
networks:
  app_net:
    driver: bridge
    ipam:
      driver: default
      config:
      -
        subnet: 172.16.238.0/24
      -
        subnet: 2001:3984:3989::/64

My nginx.conf:

user  www-data;
worker_processes  auto;
daemon off;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
	worker_connections  768;
}

http {

	upstream eulerApp {						# loadbalancing, default roundrobin
		server admin_euler:8085;
	}
	
	upstream anotherApp {					# loadbalancing, default roundrobin
		server admin_test_app1:8082;
	}
	
	server {
		listen      80;
		server_name _;
		
		#Docker DNS
		#resolver 127.0.0.11;
			
		location /abd {
			proxy_pass          http://anotherApp;
					
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";
			proxy_read_timeout 1800s;

			proxy_set_header  Host             $http_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-Protocol $scheme;
			client_max_body_size 100M; 
		}
		
		location / {
			proxy_pass          http://eulerApp;
			
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";
			proxy_read_timeout 1800s;

			proxy_set_header  Host             $http_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-Protocol $scheme;
			client_max_body_size 100M; 
		}
		
		error_page 404 /404.html;
        location = /404.html {
                root /var/www/html/;
                internal;
        }
		
		error_page 500 502 503 504 /50x.html;
i        location = /50x.html {
                root /var/www/html/;
                internal;
        }
		

	}
}

I can see the login page on myIP:8082/abd/app/test_app1. However, after login I have “undefined”.

Nothing shows on myIP:8085/app/euler

I use shinyproxy 1.1.0, Dockerfile for Shinyproxy is from the provided examples on the openanalytics Github.

What can be wrong here please?

Tx!


#18

Hi @Sasha,

Are euler and test_app1 the shiny apps you want ShinyProxy to serve?
If so, there is no need to define services for them; ShinyProxy handles the startup, routing and shutdown of these containers.
So the only services you need in that case, are shinyproxy1, shinyproxy2 and nginx.

Also, if you serve shinyproxy on a non-root context path such as /abd, you need to specify contextPath in application.yml. See https://www.shinyproxy.io/configuration/#general for more information.