File size: 7,935 Bytes
ac86214
3863641
b916cdf
4dfa41d
7c66a8f
4dfa41d
ac86214
b916cdf
 
ac86214
b916cdf
 
ac86214
ae3da12
 
 
b916cdf
 
ac86214
 
 
 
 
 
 
 
 
 
 
 
 
b916cdf
7c66a8f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2020b4
 
 
7c66a8f
f2020b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7c66a8f
 
 
 
 
f2020b4
7c66a8f
f2020b4
 
 
7c66a8f
f2020b4
 
 
 
7c66a8f
f2020b4
 
7c66a8f
f2020b4
7c66a8f
f2020b4
 
7c66a8f
f2020b4
7c66a8f
f2020b4
 
 
 
 
 
 
7c66a8f
f2020b4
 
 
7c66a8f
f2020b4
7c66a8f
f2020b4
 
 
 
7c66a8f
 
f2020b4
 
 
 
 
 
 
7c66a8f
f2020b4
 
 
 
 
7c66a8f
 
 
f2020b4
 
 
 
096295a
7c66a8f
 
 
 
 
096295a
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Use the official Python 3.9 image
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9


RUN apt-get update && apt-get install ffmpeg libsm6 libxext6 curl nginx -y

# Set the working directory to /code
WORKDIR /code

# Copy the current directory contents into the container at /code
COPY ./requirements.txt /code/requirements.txt

# Install requirements.txt 

RUN pip install pip==24.0

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

# Set up a new user named "user" with user ID 1000
RUN useradd -m -u 1000 user
# Switch to the "user" user
USER user
# Set home to the user's home directory
ENV HOME=/home/user \
	PATH=/home/user/.local/bin:$PATH

# Set the working directory to the user's home directory
WORKDIR $HOME/app

# Copy the current directory contents into the container at $HOME/app setting the owner to the user
COPY --chown=user . $HOME/app

# Create nginx configuration for WebSocket support
USER root
RUN cat > /etc/nginx/sites-available/default << 'EOF'
server {
    listen 7860;
    server_name _;

    # WebSocket support
    location /ws {
        proxy_pass http://localhost:8080/ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
    }

    # Regular HTTP requests
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
EOF

USER user

# Create a startup script for HF Spaces with nginx
RUN echo '#!/bin/bash' > start_hf_spaces.sh && \
    echo 'set -e' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'echo "πŸš€ Starting Neural OS for HF Spaces with nginx proxy"' >> start_hf_spaces.sh && \
    echo 'echo "===================================="' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“ Current directory: $(pwd)"' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“‹ Files in current directory:"' >> start_hf_spaces.sh && \
    echo 'ls -la' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Check if required files exist' >> start_hf_spaces.sh && \
    echo 'if [[ ! -f "dispatcher.py" ]]; then' >> start_hf_spaces.sh && \
    echo '    echo "❌ Error: dispatcher.py not found"' >> start_hf_spaces.sh && \
    echo '    exit 1' >> start_hf_spaces.sh && \
    echo 'fi' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'if [[ ! -f "worker.py" ]]; then' >> start_hf_spaces.sh && \
    echo '    echo "❌ Error: worker.py not found"' >> start_hf_spaces.sh && \
    echo '    exit 1' >> start_hf_spaces.sh && \
    echo 'fi' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'if [[ ! -f "static/index.html" ]]; then' >> start_hf_spaces.sh && \
    echo '    echo "❌ Error: static/index.html not found"' >> start_hf_spaces.sh && \
    echo '    exit 1' >> start_hf_spaces.sh && \
    echo 'fi' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'echo "βœ… All required files found"' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Start nginx' >> start_hf_spaces.sh && \
    echo 'echo "🌐 Starting nginx proxy..."' >> start_hf_spaces.sh && \
    echo 'sudo nginx -t && sudo nginx' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Start dispatcher on port 8080 (behind nginx)' >> start_hf_spaces.sh && \
    echo 'echo "🎯 Starting dispatcher..."' >> start_hf_spaces.sh && \
    echo 'python dispatcher.py --port 8080 > dispatcher.log 2>&1 &' >> start_hf_spaces.sh && \
    echo 'DISPATCHER_PID=$!' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“Š Dispatcher PID: $DISPATCHER_PID"' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Wait for dispatcher to start' >> start_hf_spaces.sh && \
    echo 'echo "⏳ Waiting for dispatcher to initialize..."' >> start_hf_spaces.sh && \
    echo 'sleep 5' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Test if dispatcher is responding' >> start_hf_spaces.sh && \
    echo 'echo "πŸ” Testing dispatcher health (via nginx)..."' >> start_hf_spaces.sh && \
    echo 'curl -f http://localhost:7860/ > /dev/null 2>&1' >> start_hf_spaces.sh && \
    echo 'if [ $? -eq 0 ]; then' >> start_hf_spaces.sh && \
    echo '    echo "βœ… Nginx proxy is working"' >> start_hf_spaces.sh && \
    echo 'else' >> start_hf_spaces.sh && \
    echo '    echo "⚠️ Nginx proxy test failed"' >> start_hf_spaces.sh && \
    echo 'fi' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Start worker' >> start_hf_spaces.sh && \
    echo 'echo "πŸ”§ Starting worker..."' >> start_hf_spaces.sh && \
    echo 'python worker.py --worker-address localhost:8001 --dispatcher-url http://localhost:8080 > worker.log 2>&1 &' >> start_hf_spaces.sh && \
    echo 'WORKER_PID=$!' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“Š Worker PID: $WORKER_PID"' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Wait for worker to initialize' >> start_hf_spaces.sh && \
    echo 'echo "⏳ Waiting for worker to initialize..."' >> start_hf_spaces.sh && \
    echo 'sleep 30' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Check if worker is running' >> start_hf_spaces.sh && \
    echo 'if ! kill -0 $WORKER_PID 2>/dev/null; then' >> start_hf_spaces.sh && \
    echo '    echo "❌ Worker failed to start"' >> start_hf_spaces.sh && \
    echo '    echo "πŸ“‹ Worker log:"' >> start_hf_spaces.sh && \
    echo '    tail -n 50 worker.log' >> start_hf_spaces.sh && \
    echo '    echo "πŸ“‹ Dispatcher log:"' >> start_hf_spaces.sh && \
    echo '    tail -n 50 dispatcher.log' >> start_hf_spaces.sh && \
    echo '    exit 1' >> start_hf_spaces.sh && \
    echo 'fi' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'echo "βœ… System ready!"' >> start_hf_spaces.sh && \
    echo 'echo "🌍 Web interface: http://localhost:7860 (via nginx)"' >> start_hf_spaces.sh && \
    echo 'echo "🎯 Dispatcher: http://localhost:8080 (direct)"' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“Š Dispatcher PID: $DISPATCHER_PID"' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“Š Worker PID: $WORKER_PID"' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Function to cleanup' >> start_hf_spaces.sh && \
    echo 'cleanup() {' >> start_hf_spaces.sh && \
    echo '    echo "πŸ›‘ Shutting down..."' >> start_hf_spaces.sh && \
    echo '    kill $DISPATCHER_PID $WORKER_PID 2>/dev/null || true' >> start_hf_spaces.sh && \
    echo '    sudo nginx -s quit 2>/dev/null || true' >> start_hf_spaces.sh && \
    echo '    exit 0' >> start_hf_spaces.sh && \
    echo '}' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo 'trap cleanup SIGINT SIGTERM' >> start_hf_spaces.sh && \
    echo '' >> start_hf_spaces.sh && \
    echo '# Keep the script running' >> start_hf_spaces.sh && \
    echo 'echo "πŸ“‹ Following logs (Ctrl+C to stop):"' >> start_hf_spaces.sh && \
    echo 'tail -f dispatcher.log worker.log &' >> start_hf_spaces.sh && \
    echo 'TAIL_PID=$!' >> start_hf_spaces.sh && \
    echo 'wait $DISPATCHER_PID' >> start_hf_spaces.sh && \
    echo 'kill $TAIL_PID 2>/dev/null || true' >> start_hf_spaces.sh && \
    chmod +x start_hf_spaces.sh

# Give user sudo permissions for nginx
USER root
RUN echo "user ALL=(ALL) NOPASSWD: /usr/sbin/nginx, /usr/sbin/nginx -t, /usr/sbin/nginx -s quit" >> /etc/sudoers
USER user

CMD ["bash", "start_hf_spaces.sh"]