When I try to run the Open AI Gym sample code in a docker container, I get the following error message:
Terminal
Traceback (most recent call last):
File "hello_gym.py", line 8, in <module>
env.render()
File "/usr/local/lib/python3.6/dist-packages/gym/core.py", line 240, in render
return self.env.render(mode, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/gym/envs/classic_control/cartpole.py", line 174, in render
from gym.envs.classic_control import rendering
File "/usr/local/lib/python3.6/dist-packages/gym/envs/classic_control/rendering.py", line 25, in <module>
from pyglet.gl import *
File "/usr/local/lib/python3.6/dist-packages/pyglet/gl/__init__.py", line 244, in <module>
import pyglet.window
File "/usr/local/lib/python3.6/dist-packages/pyglet/window/__init__.py", line 1880, in <module>
gl._create_shadow_window()
File "/usr/local/lib/python3.6/dist-packages/pyglet/gl/__init__.py", line 220, in _create_shadow_window
_shadow_window = Window(width=1, height=1, visible=False)
File "/usr/local/lib/python3.6/dist-packages/pyglet/window/xlib/__init__.py", line 165, in __init__
super(XlibWindow, self).__init__(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/pyglet/window/__init__.py", line 570, in __init__
display = pyglet.canvas.get_display()
File "/usr/local/lib/python3.6/dist-packages/pyglet/canvas/__init__.py", line 94, in get_display
return Display()
File "/usr/local/lib/python3.6/dist-packages/pyglet/canvas/xlib.py", line 123, in __init__
raise NoSuchDisplayException('Cannot connect to "%s"' % name)
pyglet.canvas.xlib.NoSuchDisplayException: Cannot connect to "None"
The execution environment is as follows.
version | |
---|---|
OS | Ubuntu18.04 |
python | 3.6 |
gym | 0.18.0 |
pyglet | 1.5.0 |
xvfb | 2:1.19.6 |
x11vnc | 0.9.13 |
I'm trying to set vnc in a Ubintu 18.04 based docker container and see the render () output in a browser.
--VNC is not set --X display is not set --gym sample code error (around render) --The version of pyglet does not match (pyglet was up to date)
Here is the sample code for the gym:
sample.py
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
env.render()
env.step(env.action_space.sample()) # take a random action
env.close()
(Actually, this code causes an error for another reason, but that's another article ...)
The DISPLAY was not set.
Check the environment variables in the terminal.
Terminal
$ printenv
The list is displayed in a row
Terminal
Abbreviation
LANG=C.UTF-8
OLDPWD=/home/user
VISIBLE=now
USER=user
PWD=/home/user/workspace
HOME=/home/user
Abbreviation
There is no indication of DISPLAY =
. I should have set it ...
I tried the following three methods, but they didn't work. If you want to know the solution quickly, Jump
Originally it was set in the Dockerfile (I thought it was done)
Dockerfile
ENV DISPLAY=:0
But I couldn't set the environment variables in the container.
docker run
The next method I tried was this method.
Terminal
docker run -e DISPLAY=$DISPLAY Below abbreviation
By the way, even if I changed -e
to --env
, it didn't work lol
startup.sh
startup.sh
is, roughly speaking, a shell script that can be executed when a container is started.
(I just don't understand w)
You can write the CMD
command at the end of the Dockerfile, but if you want to execute multiple commands,
Execute them by writing them in startup.sh
.
Dockerfile
CMD ["/startup.sh"]
The reason I used startup.sh
is that I wantedssh
and vnc
to be started by supervisord
, so /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
is at least I had to run it in bash.
Therefore, I wrote the command on two lines.
startup.sh
#!/bin/bash
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
export DISPLAY=:0
After all, this method did not resolve the error.
Describe as follows in the Dockerfile.
RUN echo "export DISPLAY=:0" >> /etc/profile
You have now set the environment variable inside the container to DISPLAY.
If you get the error pyglet.canvas.xlib.NoSuchDisplayException: Cannot connect to" None "
when you run gym
inside the docker container,
The DISPLAY environment variable may not be set.
I was able to set it by executing RUN echo" export DISPLAY =: 0 ">>/etc/profile
in the Dockerfile.