# NP Replica This project provides a local Chinese web replica of the core NUPACK `analysis/input` workflow. ## Run ```bash docker compose up --build -d ``` Open `http://127.0.0.1:18765`. ## Reverse Proxy The service listens on port `18765`. The current local deployment is reverse proxied as `npt.lihato.icu`. Traefik only performs TLS termination, compression, and reverse proxying for `npt`; authentication is enforced by this application. ## Deploying the independent np instance `np.lihato.icu` runs independently on `100.64.0.11`. Do not copy the `npt` OIDC values unchanged. In the `np-replica` service of the `docker-compose.yml` deployed on `.11`, use: ```yaml ports: - "100.64.0.11:18765:18765" environment: NP_AUTH_REQUIRED: 1 NP_OIDC_ISSUER: https://auth.lihato.icu/application/o/nupack-account/ NP_OIDC_CLIENT_ID: np-replica-web NP_OIDC_REDIRECT_URI: https://np.lihato.icu/auth/callback NP_OIDC_POST_LOGOUT_URI: https://np.lihato.icu/ ``` The `NP_OIDC_*` variables belong on the web service (`np-replica`); the worker does not perform browser login. Preserve the existing calculation settings, including `NP_WORKER_CONCURRENCY=16`, `NP_PER_JOB_THREAD_LIMIT=4`, and `NP_NUPACK_CACHE_GB=8.0`. After editing the Compose file on `.11`, recreate the web container: ```bash docker compose up -d --force-recreate np-replica ``` If the deployed image predates the account/OIDC changes, rebuild both application containers instead: ```bash docker compose up -d --build --force-recreate np-replica np-worker ``` Verify the result: ```bash curl -I https://np.lihato.icu/ curl -I 'https://np.lihato.icu/auth/login?next=%2F' ``` The first response should redirect to `/auth/login?next=%2F`. The second `Location` header must contain all of the following: - `client_id=np-replica-web` - `redirect_uri=https%3A%2F%2Fnp.lihato.icu%2Fauth%2Fcallback` - `code_challenge_method=S256` If it contains `npt-replica-web` or `npt.lihato.icu`, the `.11` container is still running with the wrong environment and must be recreated. ## 容器资源配置 当前 `docker-compose.yml` 面向 64 核 / 64 GB 级别的服务器配置,服务拆成三个容器: - `redis`:只保存实时队列、运行状态和会话缓存,限制为 `mem_limit: 3g`。Redis 开启 AOF,数据写入 `./runtime/redis`。 - `np-replica`:Web/API 容器,限制为 `mem_limit: 4g`,负责页面、登录、历史记录、任务提交和状态查询。它不应该承担大规模计算。 - `np-worker`:后台计算容器,限制为 `mem_limit: 56g`,负责实际 NUPACK 计算。大任务应该由这个容器消耗 CPU 和内存。 计算相关环境变量需要在 `np-replica` 和 `np-worker` 中保持一致: - `NP_WORKER_CONCURRENCY=16`:最多同时执行 16 个后台任务,超过后进入 Redis 队列等待。 - `NP_PER_JOB_THREAD_LIMIT=4`:单个任务最多使用 4 个 native 计算线程,同时写入 `OMP_NUM_THREADS`、`OPENBLAS_NUM_THREADS`、`MKL_NUM_THREADS`、`NUMEXPR_NUM_THREADS`、`VECLIB_MAXIMUM_THREADS`、`GOTO_NUM_THREADS`,并设置 `nupack.config.threads`。 - `NP_NUPACK_CACHE_GB=8.0`:单个 NUPACK 进程可使用的缓存上限。 - `NP_JOB_TTL_SECONDS=3600`:Redis 中实时任务状态的保留时间;长期历史记录写入 SQLite。 理论上当前峰值为 `16 * 4 = 64` 个 native 计算线程。若机器被压满,优先把 `NP_WORKER_CONCURRENCY` 从 `16` 降到 `8` 或 `4`;如果单任务仍过重,再把 `NP_PER_JOB_THREAD_LIMIT` 从 `4` 降到 `2` 或 `1`。`np-replica` 的内存不建议调高来跑计算,应该把计算压力留给 `np-worker`。 设计任务默认使用官方行为:固定序列 target 也参与 `tube_design` / `complex_design`。如果确认某些 target 完全固定、只需要展示结果、不需要参与优化,可在页面中把 “固定目标策略” 改为 “剥离固定目标以提速”,这样会减少 off-target 集合和优化搜索量。 ## Endpoints - `GET /` - `GET /health` - `GET /api/example` - `POST /api/analyze` - `POST /api/jobs` - `GET /api/jobs/` ## Persistent Shares Live jobs and sessions are stored in Redis when `NP_REDIS_URL` is enabled. Account history and share links are stored in `./runtime/account/np-replica.sqlite3`; back up both runtime directories when moving the deployment. ## Notes - `tube` mode supports strand concentrations and `SetSpec(max_size=...)`. - `complex` mode supports explicit complex definitions such as `A+B`. - Pair matrices are returned as a preview block to keep responses manageable. - The Docker image compiles ViennaRNA `RNAplot` from `rna/ViennaRNA-2.7.2.tar.gz` and embeds SVG structure plots into MFE results. - Multistrand MFE plots now use a split-strand layout by default when a structure contains `+`, with `RNAplot` retained as the fallback path. - The web UI supports Chinese and English switching, account-scoped cloud history, result export, share controls, and async polling for submitted jobs. - Docker now starts three services: `np-replica`, `np-worker`, and `redis`. - Async jobs use Redis-backed storage and queueing when `NP_REDIS_URL` is configured; otherwise the app falls back to the older in-memory mode. - The browser-facing API and page behavior stay the same after enabling Redis-backed jobs. - Worker concurrency is controlled by `NP_WORKER_CONCURRENCY` and defaults to `2`. - Per-job native thread usage is capped by `NP_PER_JOB_THREAD_LIMIT` and defaults to `1` to prevent a single analysis from monopolizing the machine. - `NP_STRUCTURE_PLOT_MODE` supports `auto` (default), `split`, and `rnaplot`. - Static pages are served with ETag-based browser caching; JSON API responses remain uncached. - The force-directed structure viewer lazy-loads D3 only when that view is opened, so the initial page load is not blocked by the external CDN. - `/health` uses Redis queue length plus a running-job set instead of scanning every historical job on each poll. - Application login uses the public Authentik issuer at `https://auth.lihato.icu/` with Authorization Code + PKCE. - The current `npt` instance uses issuer `/application/o/nupack-account-npt/`, client `npt-replica-web`, callback `https://npt.lihato.icu/auth/callback`, and logout return `https://npt.lihato.icu/`. - For the independent `np` deployment on `100.64.0.11`, set `NP_OIDC_ISSUER=https://auth.lihato.icu/application/o/nupack-account/`, `NP_OIDC_CLIENT_ID=np-replica-web`, `NP_OIDC_REDIRECT_URI=https://np.lihato.icu/auth/callback`, and `NP_OIDC_POST_LOGOUT_URI=https://np.lihato.icu/`. - Redis stores the live queue and login sessions. SQLite WAL at `/data/np-replica.sqlite3` stores users, owned jobs, compressed inputs/results/errors, usage totals, and durable share links. - History and job APIs enforce ownership by the Authentik OIDC subject. Public share links expose only the selected record and can be disabled or given an expiry by its owner.