问题描述
我是Docker的一个完整的初学者,所以请对我轻松一点。
我正在尝试在Raspberry Pi 3B的Docker容器中部署Django项目,但是在访问GPIO端口时遇到问题。
每次我尝试使用“ sudo docker-compose up”初始化Docker 我收到错误消息:“ RuntimeError:无法访问/ dev / mem。尝试以root身份运行!”
根据我的阅读,为了使Docker容器与GPIO端口通信,“用户”必须是“ gpio”组的一部分。
我的问题是:
- 如何使用户成为Docker文件或docker-compose.yml中GPIO组的成员?
- 是否有更好的方法可以从Docker获得对GPIO端口的访问?
Docker文件:
FROM python:3.8-alpine
ENV PATH="/scripts:${PATH}"
COPY ./requirements.txt /requirements.txt
RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers
RUN pip install -r /requirements.txt
RUN pip install RPi.GPIO
RUN pip install apscheduler
RUN apk del .tmp
RUN mkdir /poolproject
COPY ./poolproject /poolproject
WORKDIR /poolproject
COPY ./scripts /scripts
RUN chmod +x /scripts/*
RUN mkdir -p /vol/web/media
RUN mkdir -p /vol/web/static
RUN adduser -D user
RUN chown -R user:user /vol
RUN chmod -R 755 /vol/web
USER user
CMD ["entrypoint.sh"]
docker-compose.yml
version: '3.7'
services:
app:
privileged: true
build:
context: .
ports:
- "8000:8000"
volumes:
- ./poolproject:/poolproject
command: sh -c "python manage.py runserver 0.0.0.0:8000"
environment:
- DEBUG=1
解决方法
我道歉;我撤回了先前的答案,因为我错过了privileged: true
中已经有docker-compose.yml
的事实。您有其他问题。
首先,来自RPi.GPIO
的错误具有误导性:它实际上并不想访问/dev/mem
;它希望访问/dev/gpiomem
,该主机上的主机具有以下权限:
pi@raspberrypi:~ $ ls -l /dev/gpiomem
crw-rw---- 1 root gpio 246,0 Sep 7 09:02 /dev/gpiomem
gpio
组有997
的情况:
pi@raspberrypi:~ $ getent group gpio
gpio:x:997:pi
这意味着我们需要安排您的Web服务在容器内以997
的gid运行。为此,我们可以在gpio
内添加Dockerfile
组,然后让您的user
成为该组的成员:
RUN addgroup -g 997 gpio
RUN adduser -D -G gpio user
有了此更改,我可以运行一些测试代码而不会出错。此外,不再需要启用privileged
模式。我们可以将privileged: true
中的docker-compose.yml
替换为devices
条目以仅显示/dev/gpiomem
设备。
测试环境
这就是我用来测试情况的一切。
这是我的Dockerfile
:
FROM python:3.8-alpine
RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers
RUN pip install RPi.GPIO
RUN addgroup -g 997 gpio
RUN adduser -D -G gpio user
RUN mkdir -p /scripts
RUN chown -R user:gpio /scripts
COPY gpiotest.py /scripts/gpiotest.py
RUN chmod 755 /scripts/gpiotest.py
CMD python /scripts/gpiotest.py
USER user
这是我的docker-compose.yml
:
version: '3.7'
services:
app:
build:
context: .
devices:
- /dev/gpiomem:/dev/gpiomem
这是我的gpiotest.py
脚本:
#!/usr/bin/python
import sys
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)
while True:
val = GPIO.input(17)
print('value:',val)
sys.stdout.flush()
time.sleep(1)