File size: 4,968 Bytes
f7e81bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8de2be
f7e81bd
c8de2be
f7e81bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c90c95d
f7e81bd
c8de2be
8d2a3b3
c8de2be
 
 
 
022e774
9bd7c0b
 
 
 
 
022e774
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05c3ccc
 
8d2a3b3
b5dbacc
ea45eb7
 
 
 
 
f7e81bd
 
 
c8de2be
 
 
c90c95d
 
 
 
 
 
 
 
 
 
 
f7e81bd
 
 
 
 
 
 
 
 
 
 
 
 
c90c95d
f7e81bd
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 1. Start from a slim Python 3.11 base image
FROM python:3.11-slim

# 2. Set Environment Variables
# - DEBIAN_FRONTEND: Prevents installers from asking interactive questions
# - PYTHONUNBUFFERED/PYTHONDONTWRITEBYTECODE: Standard Python-in-Docker settings
# - PYVISTA_OFF_SCREEN/DISPLAY: Crucial for running PyVista headless (off-screen)
#   by telling it to use a "virtual" display at address :99
ENV DEBIAN_FRONTEND=noninteractive \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    HOME=/home/user \
    PATH=/home/user/.local/bin:$PATH \
    PYVISTA_OFF_SCREEN=true \
    DISPLAY=:99 \
    VTK_SILENCE_GET_VOID_POINTER_WARNINGS=1

# 3. Install System Dependencies
# Added 'git' here because we need it to clone aqc-research
RUN apt-get update && apt-get install -y --no-install-recommends \
  build-essential cmake wget xvfb nginx git \
    libosmesa6 libosmesa6-dev \
    libgl1 libgl1-mesa-dev \
    libegl1 libegl1-mesa-dev \
    libglu1-mesa libglu1-mesa-dev \
    libgles2-mesa-dev \
    libx11-6 libxt6 libxrender1 libsm6 libice6 \
    && rm -rf /var/lib/apt/lists/*

# 4. Create a non-root user for security
RUN useradd -m -u 1000 user
WORKDIR /home/user/app

# 5. Install Python dependencies (optimized)
# We copy *only* requirements.txt first and install it.
# This "layer" is cached by Docker. If you only change app.py later,
# Docker skips this step, making builds much faster.
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip setuptools wheel \
 && python3 -m pip install --no-cache-dir -r requirements.txt

# 6. Copy the rest of the application code
# This copies app.py, delta_impulse_generator.py, etc.
# We set the owner to our new 'user'.
COPY --chown=user:user . .
COPY docker/nginx.conf /etc/nginx/nginx.conf

# ---------------------------------------------------------------------------
# Create the 'aqc_venv' and install dependencies
# ---------------------------------------------------------------------------
RUN python3 -m venv utils/aqc_venv && \
    # 1. Upgrade pip inside the new venv
    utils/aqc_venv/bin/pip install --upgrade pip setuptools wheel && \
    # 2. Install EXACT versions FIRST (before any library that has qiskit dependency)
    utils/aqc_venv/bin/pip install \
        "qiskit==1.3.1" \
        "qiskit-aer==0.16.4" \
        "qiskit-algorithms==0.4.0" \
        "qiskit-qasm3-import==0.6.0" \
        "qiskit-experiments==0.6.1" \
        "qiskit-ibm-experiment==0.4.8" \
        "numpy==1.26.4" \
        "scipy==1.16.3" \
        "sympy==1.14.0" \
        "openfermion==1.7.1" \
        "cirq-core==1.6.1" \
        "physics-tenpy==1.0.7" \
        "lmfit==1.3.4" \
        "h5py==3.15.1" && \
    # 3. Clone aqc-research inside utils
    cd utils && \
    git clone https://github.com/bjader/aqc-research.git && \

    # 4. Install aqc-research with --no-deps (won't upgrade qiskit)

    /home/user/app/utils/aqc_venv/bin/pip install --no-deps ./aqc-research && \

    # 5. Install adapt-aqc with --no-deps

    /home/user/app/utils/aqc_venv/bin/pip install --no-deps -e ./adapt-aqc && \

    # 6. VERIFY: Print versions to confirm

    echo "=== Qiskit versions ===" && \

    /home/user/app/utils/aqc_venv/bin/pip list | grep -i qiskit && \

    /home/user/app/utils/aqc_venv/bin/python --version



# Prepare writable directories for nginx (running as non-root later)

RUN mkdir -p /tmp/nginx/body /tmp/nginx/proxy /tmp/nginx/fastcgi /tmp/nginx/uwsgi /tmp/nginx/scgi \

  && touch /tmp/nginx.access.log /tmp/nginx.error.log \

  && chown -R user:user /tmp/nginx /tmp/nginx.access.log /tmp/nginx.error.log



# 7. Switch to the non-root user

USER user



# Note: We do NOT set PYTHONPATH for adapt-aqc here because it is installed 

# inside the 'aqc_venv' which your code calls via subprocess.



# Default runtime configuration for multiprocess layout

ENV OMP_NUM_THREADS=1 \

  APP_HOST=127.0.0.1 \

  APP_PORT=8700 \

  EM_APP_PORT=8701 \

  QLBM_APP_PORT=8702 \

  EM_HOST=127.0.0.1 \

  QLBM_HOST=127.0.0.1 \

  EM_IFRAME_SRC=/em/ \

  QLBM_IFRAME_SRC=/qlbm/



# 8. Expose the port the app will run on

EXPOSE 7860



# 9. Healthcheck (good practice for hosting platforms)

HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \

  CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT:-7860}/ || exit 1

# 10. Start Command
# This command does two things:
# a) Starts the X Virtual FrameBuffer (Xvfb) in the background (&) on display :99
# b) 'exec' runs your app. Using 'exec' is important as it makes the Python
#    process the main one, which properly handles signals (like stopping the container).
#    '--host 0.0.0.0' is ESSENTIAL to make the server accessible from outside the container.
CMD ["sh", "-c", "Xvfb :99 -screen 0 1024x768x24 >/dev/null 2>&1 & nginx && exec python3 app.py --server --host ${APP_HOST:-127.0.0.1} --port ${APP_PORT:-8700}"]