### 流程
#### `浏览器--->noVNC--->xvfb虚拟桌面--->pygame程序`
### xvfb安装
#### 编辑Dockerfile
```bash
cat Dockerfile
```
```bash
FROM ubuntu:xenial
LABEL maintainer "sheyinsong"
EXPOSE 5900 6099
ENV \
DEBIAN_FRONTEND="nonintractive" \
X11VNC_PASSWORD="password"
RUN sed -i -e s#security.ubuntu.com#mirrors.aliyun.com#g -e s#archive.ubuntu.com#mirrors.aliyun.com#g /etc/apt/sources.list
RUN apt-get update -y
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:jonathonf/python-3.6
RUN apt-get update -y
RUN apt-get install -y xvfb x11vnc python3.6 libglib2.0-0
RUN apt-get install -y curl
RUN /bin/cp /usr/bin/python3.6 /usr/bin/python
RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6
RUN pip install pygame
ADD ./start.sh /opt/start.sh
ENTRYPOINT [ "bash","/opt/start.sh" ]
```
#### 创建start.sh脚本
```bash
cat start.sh
```
```bash
#!/bin/bash
screen_width=${1:-800}
screen_height=${2:-600}
screen_depth=${3:-16}
run_file=${4:-"main.py"}
nohup Xvfb :1 -screen 0 ${screen_width}x${screen_height}x${screen_depth} >/dev/null 2>&1 &
sleep 0.1
nohup /usr/bin/x11vnc -display :1.0 -passwd ${X11VNC_PASSWORD:-password} >/dev/null 2>&1 &
sleep 0.1
DISPLAY=:1.0
export DISPLAY
cd /run_game
PYTHONIOENCODING=utf-8 python $run_file
```
#### 创建pygame镜像
```bash
docker build -t sheyinsong/pygame:1.0 .
```
### Novnc安装
#### 编辑Dockerfile
```bash
cat Dockerfile
```
```bash
FROM python
MAINTAINER sys "sheyinsong"
RUN apt-get update -y
RUN apt-get upgrade -y
RUN apt-get install -y python-numpy
RUN apt-get clean
RUN pip install redis
RUN pip install simplejson
ADD ./noVNC/ /noVNC/
CMD ["python", "/noVNC/utils/websockify/run", "--web", "/noVNC", "0.0.0.0:10240", "--target-config", "/noVNC/token.list"]
```
#### 下载noVNC
下载地址:https://github.com/novnc/noVNC/releases/
#### 创建token.list(token映射到对应的socket)
```bash
cat noVNC/token.list #noVNC下载好后,到根目录创建该文件
```
```bash
a35fe7f7fe8217b4369a0af4244d1fca: 127.0.0.1:5000
03b264c595403666634ac75d828439bc: 127.0.0.1:5001
...
```
#### 创建novnc镜像
```bash
docker build -t sheyinsong/noVNC:1.0 .
```
#### 运行novnc容器
```bash
docker run -d --network="host" --restart=always -it sheyinsong/novnc:1.0
```
#### 创建生成NoVNC地址的脚本
```bash
cat pygame_url.py
```
```python
#coding:utf-8
import sys
import os
import random
import subprocess
import hashlib
import time
import argparse
import json
parser = argparse.ArgumentParser()
parser.add_argument("pygame_dir",nargs = 1, help="Pygame progrom root directory")
parser.add_argument("--screen-width", help="Xvfb screen width,default value 800", default=800, type=int)
parser.add_argument("--screen-height", help="Xvfb screen heigth,default value 600", default=600, type=int)
parser.add_argument("--screen-depth", help="Xvfb screen depth,default value 16", default=16, type=int)
parser.add_argument("--run-file", help="run specify file", default='main.py')
args = parser.parse_args()
pygame_dir=args.pygame_dir[0]
screen_width=str(args.screen_width)
screen_height=str(args.screen_height)
screen_depth=str(args.screen_depth)
run_file=args.run_file
pygame_image='sheyinsong/pygame:1.0'
sample_url='http://192.168.50.252:10240/vnc_lite.html?path=?token=' #地址为noVNC运行的地址
dict_data={}
if not os.path.isdir(pygame_dir):
dict_data['result']='error'
dict_data['msg']=pygame_dir+'程序目录不存在.'
print(json.dumps(dict_data))
exit(1)
pygame_main=os.path.join(pygame_dir,'main.py')
if not os.path.exists(pygame_main):
dict_data['result']='error'
dict_data['msg']=pygame_dir+'程序目录不存在文件main.py.'
print(json.dumps(dict_data))
exit(1)
source = open(pygame_main, 'r').read() + '\n'
try:
code_obj=compile(source, pygame_main, 'exec')
except Exception as e:
dict_data['result']='error'
dict_data['msg']=str(e)
print(json.dumps(dict_data))
exit(1)
def get_free_random_port():
command="netstat -ltnp |grep x11vnc|awk '{ print $4}'|awk -F: '{ print $NF}'"
p = subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True)
usage_port_list=[ int(port) for port in p.stdout.read().split('\n') if port != '' ]
free_post_list=set(range(5000,6000))-set(usage_port_list)
return random.choice(list(free_post_list))
def convert_png():
command="find {0} -name *.png|while read line;do; convert $line $line; done".format(pygame_dir)
subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True)
free_random_port=get_free_random_port()
convert_png()
docker_out = subprocess.Popen(['docker', 'run','-ti','--cpus','0.2', '-d', '-p', str(free_random_port)+':5900', '-v', pygame_dir+':/run_game', pygame_image, screen_width, screen_height, screen_depth, run_file], stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
stdout,stderr = docker_out.communicate()
time.sleep(1)
containter_id=stdout.strip()
p1 = subprocess.Popen('docker logs --tail 100 '+containter_id,stdout=subprocess.PIPE,shell=True)
p2 = subprocess.Popen('grep -A 1000 Traceback',stdin=p1.stdout,stdout=subprocess.PIPE,shell=True)
docker_out=p2.stdout.read()
if docker_out:
dict_data['result']='error'
dict_data['msg']=docker_out.replace('\r\n','\\n').replace('"','\'')
print(json.dumps(dict_data))
else:
token=hashlib.md5(str(free_random_port)).hexdigest()
url=sample_url+token+'&password=password'
dict_data['result']='ok'
dict_data['msg']=docker_out.replace('\r\n','\\n').replace('"','\'')
dict_data['url']=url
dict_data['cid']=containter_id
print(json.dumps(dict_data))
```
#### 运行脚本
```bash
python /data/app/pygame/pygame_url.py /data/app/pygame/Puser/ --run-file main.py
```
程序返回结果(url为访问pygame的地址)
```json
{"msg": "", "url": "http://192.168.50.252:10240/vnc_lite.html?path=?token=fcd4c889d516a54d5371f00e3fdd70dc&password=password", "result": "ok", "cid": "23cac4bb78e93f3fb1c7232d5778ad99468cd86cc927cfd8e5161e485239b46b"}
```
`/data/app/pygame/Puser/` 为程序根目录
`main.py` 为运行pygame的入口程序
### 页面访问pygame
![](https://files.ynotes.cn/pygame_demo.png)
Строительная башня тура оптимально подходит и для ремонтных и отделочных работ, и для сбора урожая. В конструкции каждой модели предусмотрены колеса, благодаря которым вышку споро перемещать с места для владение быть необходимости. Особенности и <a href=https://vk.com/@vyshki_tur-kak-sobirat-vyshki-tury>Вышка тура Щучин</a> Прочность. Воеже того чтобы обеспечить жесткость рам, некоторый производители снабжают алюминиевую вышку-туру диагональными металлическими стяжками. Благодаря им фазис
0 0人回复