Separate Python and Rust into python/ and rust/ with per-stack Dockerfiles
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -27,11 +27,11 @@ dist/
|
||||
.eggs/
|
||||
|
||||
# Rust / maturin build artifacts
|
||||
myfsio_core/target/
|
||||
myfsio_core/Cargo.lock
|
||||
python/myfsio_core/target/
|
||||
python/myfsio_core/Cargo.lock
|
||||
|
||||
# Rust engine build artifacts
|
||||
myfsio-engine/target/
|
||||
rust/myfsio-engine/target/
|
||||
|
||||
# Local runtime artifacts
|
||||
logs/
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
ENGINE="${ENGINE:-rust}"
|
||||
|
||||
exec python run.py --prod --engine "$ENGINE"
|
||||
@@ -11,5 +11,7 @@ htmlcov
|
||||
logs
|
||||
data
|
||||
tmp
|
||||
tests
|
||||
myfsio_core/target
|
||||
myfsio-engine/target
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
@@ -1,9 +1,9 @@
|
||||
FROM python:3.14.3-slim
|
||||
FROM python:3.14.3-slim AS builder
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
WORKDIR /build
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends build-essential curl \
|
||||
@@ -12,27 +12,34 @@ RUN apt-get update \
|
||||
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
COPY requirements.txt ./
|
||||
RUN pip install --no-cache-dir maturin
|
||||
|
||||
COPY myfsio_core ./myfsio_core
|
||||
RUN cd myfsio_core \
|
||||
&& maturin build --release --out /wheels
|
||||
|
||||
|
||||
FROM python:3.14.3-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt ./
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
COPY --from=builder /wheels/*.whl /tmp/
|
||||
RUN pip install --no-cache-dir /tmp/*.whl && rm /tmp/*.whl
|
||||
|
||||
RUN pip install --no-cache-dir maturin \
|
||||
&& cd myfsio_core \
|
||||
&& maturin build --release \
|
||||
&& pip install target/wheels/*.whl \
|
||||
&& cd ../myfsio-engine \
|
||||
&& cargo build --release \
|
||||
&& cp target/release/myfsio-server /usr/local/bin/myfsio-server \
|
||||
&& cd .. \
|
||||
&& rm -rf myfsio_core/target myfsio-engine/target \
|
||||
&& pip uninstall -y maturin \
|
||||
&& rustup self uninstall -y
|
||||
COPY app ./app
|
||||
COPY templates ./templates
|
||||
COPY static ./static
|
||||
COPY run.py ./
|
||||
COPY docker-entrypoint.sh ./
|
||||
|
||||
RUN chmod +x docker-entrypoint.sh
|
||||
|
||||
RUN mkdir -p /app/data \
|
||||
RUN chmod +x docker-entrypoint.sh \
|
||||
&& mkdir -p /app/data \
|
||||
&& useradd -m -u 1000 myfsio \
|
||||
&& chown -R myfsio:myfsio /app
|
||||
|
||||
@@ -41,8 +48,7 @@ USER myfsio
|
||||
EXPOSE 5000 5100
|
||||
ENV APP_HOST=0.0.0.0 \
|
||||
FLASK_ENV=production \
|
||||
FLASK_DEBUG=0 \
|
||||
ENGINE=rust
|
||||
FLASK_DEBUG=0
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD python -c "import requests; requests.get('http://localhost:5000/myfsio/health', timeout=2)"
|
||||
4
python/docker-entrypoint.sh
Normal file
4
python/docker-entrypoint.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
exec python run.py --prod
|
||||
@@ -5,7 +5,6 @@ import argparse
|
||||
import atexit
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import warnings
|
||||
import multiprocessing
|
||||
@@ -75,49 +74,6 @@ def _serve_granian(target: str, port: int, config: Optional[AppConfig] = None) -
|
||||
server.serve()
|
||||
|
||||
|
||||
def _find_rust_binary() -> Optional[Path]:
|
||||
candidates = [
|
||||
Path("/usr/local/bin/myfsio-server"),
|
||||
Path(__file__).parent / "myfsio-engine" / "target" / "release" / "myfsio-server.exe",
|
||||
Path(__file__).parent / "myfsio-engine" / "target" / "release" / "myfsio-server",
|
||||
Path(__file__).parent / "myfsio-engine" / "target" / "debug" / "myfsio-server.exe",
|
||||
Path(__file__).parent / "myfsio-engine" / "target" / "debug" / "myfsio-server",
|
||||
]
|
||||
for p in candidates:
|
||||
if p.exists():
|
||||
return p
|
||||
return None
|
||||
|
||||
|
||||
def serve_rust_api(port: int, config: Optional[AppConfig] = None) -> None:
|
||||
binary = _find_rust_binary()
|
||||
if binary is None:
|
||||
print("ERROR: Rust engine binary not found. Build it first:")
|
||||
print(" cd myfsio-engine && cargo build --release")
|
||||
sys.exit(1)
|
||||
|
||||
env = os.environ.copy()
|
||||
env["PORT"] = str(port)
|
||||
env["HOST"] = _server_host()
|
||||
if config:
|
||||
env["STORAGE_ROOT"] = str(config.storage_root)
|
||||
env["AWS_REGION"] = config.aws_region
|
||||
if config.secret_key:
|
||||
env["SECRET_KEY"] = config.secret_key
|
||||
env.setdefault("ENCRYPTION_ENABLED", str(config.encryption_enabled).lower())
|
||||
env.setdefault("KMS_ENABLED", str(config.kms_enabled).lower())
|
||||
env.setdefault("LIFECYCLE_ENABLED", str(config.lifecycle_enabled).lower())
|
||||
env.setdefault("RUST_LOG", "info")
|
||||
|
||||
print(f"Starting Rust S3 engine: {binary}")
|
||||
proc = subprocess.Popen([str(binary)], env=env)
|
||||
try:
|
||||
proc.wait()
|
||||
except KeyboardInterrupt:
|
||||
proc.terminate()
|
||||
proc.wait(timeout=5)
|
||||
|
||||
|
||||
def serve_api(port: int, prod: bool = False, config: Optional[AppConfig] = None) -> None:
|
||||
if prod:
|
||||
_serve_granian("app:create_api_app", port, config)
|
||||
@@ -271,7 +227,6 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--ui-port", type=int, default=5100)
|
||||
parser.add_argument("--prod", action="store_true", help="Run in production mode using Granian")
|
||||
parser.add_argument("--dev", action="store_true", help="Force development mode (Flask dev server)")
|
||||
parser.add_argument("--engine", choices=["python", "rust"], default=os.getenv("ENGINE", "python"), help="API engine: python (Flask) or rust (myfsio-engine)")
|
||||
parser.add_argument("--check-config", action="store_true", help="Validate configuration and exit")
|
||||
parser.add_argument("--show-config", action="store_true", help="Show configuration summary and exit")
|
||||
parser.add_argument("--reset-cred", action="store_true", help="Reset admin credentials and exit")
|
||||
@@ -325,16 +280,8 @@ if __name__ == "__main__":
|
||||
else:
|
||||
print("Running in development mode (Flask dev server)")
|
||||
|
||||
use_rust = args.engine == "rust"
|
||||
|
||||
if args.mode in {"api", "both"}:
|
||||
if use_rust:
|
||||
print(f"Starting Rust API engine on port {args.api_port}...")
|
||||
else:
|
||||
print(f"Starting API server on port {args.api_port}...")
|
||||
if use_rust:
|
||||
api_proc = Process(target=serve_rust_api, args=(args.api_port, config))
|
||||
else:
|
||||
api_proc = Process(target=serve_api, args=(args.api_port, prod_mode, config))
|
||||
api_proc.start()
|
||||
else:
|
||||
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 872 KiB After Width: | Height: | Size: 872 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user