qgis – How to Resolve ‘Could Not Connect to Any X Display’ Error for QGIS on Docker Container

dockerpyqgisqgis

I am trying and failing to establish functional environment on docker container to run some QGIS related tasks.

This is the idea: using flask app user enters input data. That information travels to server and it is user to query spatial database. Next, that data is exported to geopackage format and stored to server. After that I want to create qgs project and add geopackage to project, add qml or sld as a style, save it, zip whole folder (with QGIS project and geopackage) and send it to user.

I used docker to do this. I installed qgis/qgis image from docker hub.

The problem starts where I try to instantiate QgsApplication and it says next:

QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.**

This is the way I tried to solve problem but error repeats (also saw on gis.stackexchange):

@app.route('/')
def index():
    vers = Qgis.QGIS_VERSION
    # I got value for vers variable 
    ogr2ogr.main(["", "-f", "GPKG", "export.gpkg", "PG:dbname='dbname' host='host' port=5432 
    user='username' " "password='password'  tables=schema.table", "-skipfailures", "- 
    overwrite", "-progress"])
    gui_flag = False
    app = QgsApplication([b''], gui_flag)
    app.setPrefixPath('/usr')
    app.initQgis()
    if len(QgsProviderRegistry.instance().providerList()) == 0:
        raise RuntimeError('No data providers available.')

    strProjectName = "my_project.qgs"
    project = QgsProject.instance()
    vlayer = QgsVectorLayer("export.gpkg", "layername", "ogr")

    if not vlayer.isValid():
        print("Layer failed to load!")
    else:
        project.addMapLayer(vlayer)

    project.write(strProjectName)
    return render_template('ind.html', vers =vers)

This is Dockerfile I used to build image.
docker image build -t qgis_proj

app.py is a simple flask app with one endpoint as mentioned above.

FROM ubuntu:bionic
FROM qgis/qgis
RUN apt-get update -y
RUN apt-get install python3-pip
RUN apt-get install xvfb xserver-xephyr vnc4server -y
RUN pip3 install pyvirtualdisplay
RUN apt-get update -y
RUN Xvfb :99 -ac -noreset & 
RUN export DISPLAY=:99
RUN mkdir /app
WORKDIR /app
COPY requirements.txt /app
RUN pip3 install -r requirements.txt
RUN rm requirements.txt
RUN apt-get install wget gpg nano -y

EXPOSE 5002

ENTRYPOINT ["gunicorn", "-b", "0.0.0.0:5002", "-w", "9", "app:app"]

After building an image an run container
docker container run -d -p 5002:5002 -v /home/cug/download:/app --name download_service qgis_proj

Best Answer

This is how I found a solution: At shell I run: export QT_QPA_PLATFORM=offscreen

Then, at a python script I did this: import os from qgis.core import * os.environ["QT_QPA_PLATFORM"] = "offscreen" QgsApplication.setPrefixPath("/usr", False) qgs = QgsApplication([], False) qgs.initQgis()

This solution is based on another answer I found here

After this lines everthing worked as expected.