guydffdsdsfd commited on
Commit
70a06fc
·
verified ·
1 Parent(s): fb45ad3

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +32 -142
Dockerfile CHANGED
@@ -1,158 +1,48 @@
1
  FROM python:3.10-slim
2
 
3
- # ---------------- System deps ----------------
4
  RUN apt-get update && apt-get install -y \
5
  git \
6
  libgl1 \
7
  libglib2.0-0 \
 
8
  && rm -rf /var/lib/apt/lists/*
9
 
10
- # ---------------- Python deps ----------------
11
  RUN pip install --no-cache-dir \
12
- torch \
13
- torchvision \
14
- torchaudio \
15
- diffusers["torch"] \
16
- transformers \
17
- accelerate \
18
- safetensors \
19
- flask \
20
- flask-cors \
21
- pillow
22
-
23
- # ---------------- Env ----------------
 
 
 
24
  ENV HOME=/home/sd
25
- ENV HF_HOME=/home/sd/.cache
26
- ENV TRANSFORMERS_CACHE=/home/sd/.cache
27
- ENV DIFFUSERS_CACHE=/home/sd/.cache
 
 
28
 
29
- # ---------------- Storage ----------------
30
  RUN mkdir -p /home/sd && chmod -R 777 /home/sd
31
 
32
- # ---------------- Flask API ----------------
33
- RUN cat <<'EOF' > /app.py
34
- from flask import Flask, request, jsonify, send_file
35
- from flask_cors import CORS
36
- from diffusers import StableDiffusionXLImg2ImgPipeline, StableDiffusionXLPipeline, DPMSolverMultistepScheduler
37
- import torch, os, json, secrets
38
- from io import BytesIO
39
-
40
- app = Flask(__name__)
41
- CORS(app)
42
-
43
- # -------- Paths --------
44
- BASE = "/home/sd"
45
- WL_PATH = f"{BASE}/whitelist.txt"
46
- USAGE_PATH = f"{BASE}/usage.json"
47
- LIMITS_PATH = f"{BASE}/limits.json"
48
-
49
- DEFAULT_LIMIT = 500
50
- MODEL_ID = "stabilityai/stable-diffusion-xl-base-1.0"
51
-
52
- # -------- Init storage --------
53
- os.makedirs(BASE, exist_ok=True)
54
- for p in [WL_PATH, USAGE_PATH, LIMITS_PATH]:
55
- if not os.path.exists(p):
56
- open(p, "w").write("{}" if p.endswith(".json") else "")
57
-
58
- # -------- Load model once --------
59
- pipe = StableDiffusionXLPipeline.from_pretrained(
60
- MODEL_ID,
61
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
62
- )
63
- pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
64
- pipe = pipe.to("cuda" if torch.cuda.is_available() else "cpu")
65
-
66
- # -------- Helpers --------
67
- def whitelist():
68
- return set(open(WL_PATH).read().split())
69
-
70
- def load_json(path):
71
- try:
72
- return json.load(open(path))
73
- except:
74
- return {}
75
-
76
- def save_json(path, data):
77
- json.dump(data, open(path, "w"))
78
-
79
- # -------- Health --------
80
- @app.route("/", methods=["GET"])
81
- def health():
82
- return "Image XL API Running", 200
83
-
84
- # -------- Key generator --------
85
- @app.route("/generate-key", methods=["POST"])
86
- def generate_key():
87
- data = request.get_json() or {}
88
- unlimited = data.get("unlimited", False)
89
- limit = data.get("limit", DEFAULT_LIMIT)
90
-
91
- key = "sk-" + secrets.token_hex(16)
92
-
93
- with open(WL_PATH, "a") as f:
94
- f.write(key + "\n")
95
-
96
- limits = load_json(LIMITS_PATH)
97
- limits[key] = "unlimited" if unlimited else int(limit)
98
- save_json(LIMITS_PATH, limits)
99
-
100
- return jsonify({"key": key, "limit": limits[key]})
101
 
102
- # -------- Image generation --------
103
- @app.route("/api/generate", methods=["POST"])
104
- def generate():
105
- key = request.headers.get("x-api-key", "")
106
- if key not in whitelist():
107
- return jsonify({"error": "Unauthorized"}), 401
108
-
109
- data = request.get_json() or {}
110
- prompt = data.get("prompt", "").strip()
111
- steps = int(data.get("steps", 25))
112
- guidance = float(data.get("guidance", 7.5))
113
-
114
- if not prompt:
115
- return jsonify({"error": "Prompt required"}), 400
116
-
117
- limits = load_json(LIMITS_PATH)
118
- usage = load_json(USAGE_PATH)
119
-
120
- limit = limits.get(key, DEFAULT_LIMIT)
121
- unlimited = (limit == "unlimited")
122
-
123
- from datetime import datetime
124
- month = datetime.now().strftime("%Y-%m")
125
- used = usage.get(key, {}).get(month, 0)
126
-
127
- if not unlimited and used >= limit:
128
- return jsonify({"error": "Monthly limit reached"}), 429
129
-
130
- image = pipe(
131
- prompt=prompt,
132
- num_inference_steps=steps,
133
- guidance_scale=guidance
134
- ).images[0]
135
-
136
- usage.setdefault(key, {})[month] = used + 1
137
- save_json(USAGE_PATH, usage)
138
-
139
- buf = BytesIO()
140
- image.save(buf, format="PNG")
141
- buf.seek(0)
142
-
143
- return send_file(buf, mimetype="image/png")
144
-
145
- if __name__ == "__main__":
146
- app.run(host="0.0.0.0", port=7860)
147
- EOF
148
-
149
- # ---------------- Start ----------------
150
- RUN cat <<'EOF' > /start.sh
151
- #!/bin/bash
152
- python3 /app.py
153
- EOF
154
-
155
- RUN chmod +x /start.sh
156
 
157
  EXPOSE 7860
158
- ENTRYPOINT ["/bin/bash", "/start.sh"]
 
 
 
1
  FROM python:3.10-slim
2
 
3
+ # System dependencies
4
  RUN apt-get update && apt-get install -y \
5
  git \
6
  libgl1 \
7
  libglib2.0-0 \
8
+ wget \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
+ # Optimized Python dependencies
12
  RUN pip install --no-cache-dir \
13
+ torch==2.1.2 \
14
+ torchvision==0.16.2 \
15
+ torchaudio==2.1.2 \
16
+ --index-url https://download.pytorch.org/whl/cu118 \
17
+ && pip install --no-cache-dir \
18
+ diffusers==0.26.3 \
19
+ transformers==4.38.2 \
20
+ accelerate==0.27.2 \
21
+ safetensors==0.4.2 \
22
+ flask==3.0.3 \
23
+ flask-cors==4.0.0 \
24
+ pillow==10.2.0 \
25
+ xformers==0.0.24
26
+
27
+ # Environment variables for caching
28
  ENV HOME=/home/sd
29
+ ENV HF_HOME=/home/sd/.cache/huggingface
30
+ ENV TRANSFORMERS_CACHE=/home/sd/.cache/huggingface/models
31
+ ENV DIFFUSERS_CACHE=/home/sd/.cache/huggingface/diffusers
32
+ ENV PYTHONUNBUFFERED=1
33
+ ENV HF_ENDPOINT=https://hf-mirror.com
34
 
35
+ # Create directory with proper permissions
36
  RUN mkdir -p /home/sd && chmod -R 777 /home/sd
37
 
38
+ # Copy application code
39
+ COPY app.py /app.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/', timeout=2)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  EXPOSE 7860
46
+
47
+ # Start command
48
+ CMD ["python", "/app.py"]