Skip to content

Build & Deploy

Build

{
  "scripts": {
    "dev":      "nuxt",
    "build":    "nuxt build",
    "start":    "nuxt start",
    "generate": "nuxt generate"
  }
}

Standard Nuxt 2 scripts. No format, no lint, no test.

Production build: 1. cd polotno-editor && yarn install && yarn build → produces ../polotno-bundle.js 2. cd .. && yarn install && yarn build → produces .nuxt/dist/ 3. yarn start serves the built SPA

Typical local build: ~30-60 seconds.

Dockerfile

Multi-stage:

# Stage 1: Build polotno-editor
FROM node:20.18.3-slim AS polotno-build
WORKDIR /polotno-editor
COPY polotno-editor/ ./
# Note: node_modules will be mounted from EFS at runtime
# Build step will be handled in start script after EFS mount

# Stage 2: Prepare main project
FROM node:20.18.3-slim AS main-prep
WORKDIR /app
COPY .nuxt ./.nuxt
COPY dist ./dist
COPY static ./static
COPY nuxt.config.js ./
COPY polotno-bundle.js ./
COPY polotno-bundle.js.map ./
COPY polotno-bundle.css ./           #  only created during build; may not exist in repo
COPY polotno-bundle.css.map ./
COPY assets components helpers layouts middleware pages plugins static store ./
COPY --from=polotno-build /polotno-editor ./polotno-editor

# Stage 3: Runtime
FROM node:20.18.3-slim
RUN apt-get update && apt-get install -y \
    libnss3 libatk-bridge2.0-0 fontconfig libx11-xcb1 \
    libxcomposite1 libxdamage1 libxrandr2 libgbm1 libgtk-3-0 \
    libasound2 libpangocairo-1.0-0 libxshmfence1 libxss1 \
    nginx curl ...
WORKDIR /usr/src/app
COPY --from=main-prep /app ./
COPY nginx.conf /etc/nginx/nginx.conf
COPY start.sh /usr/src/app/start.sh
EXPOSE 80 443
HEALTHCHECK ... CMD curl -f http://localhost:80/ || exit 1
CMD ["bash", "/usr/src/app/start.sh"]

Key points:

  1. No node_modules in the image — they are mounted from EFS at runtime (per the platform pattern)
  2. .nuxt, dist, polotno-bundle.{js,css} are COPYed pre-built — meaning the build happens outside Docker, then the artifacts are bundled
  3. Puppeteer/Chrome runtime libs installed — for headless rendering inside the FE process? Verify; usually Polotno's headless rendering is server-side (polotno-node in designer-api)
  4. start.sh is the entrypoint — verify its contents (probably waits for EFS mount, starts nginx + nuxt)
  5. Has a HEALTHCHECK — good

Deploy mechanism

  • No Jenkinsfile in repo
  • No .github/workflows/ in repo
  • A push.sh is mentioned in someli-platform README but not seen here

Deploy is presumably:

  1. CI (external repo / Jenkins box) builds the image
  2. SSH to Lightsail; docker pull; docker stop old; docker run new
  3. EFS provides node_modules

This is opaque from the repo alone. Recommendation: commit a CI workflow or a Jenkinsfile.

EFS-mounted node_modules

Same pattern as someli-platform. Pros:

  • Image is smaller
  • node_modules can be updated without rebuilding the image
  • Multiple containers share the same node_modules (storage saved)

Cons:

  • Container startup waits for EFS mount (up to 60s per someli-platform/start.sh)
  • Inconsistent node_modules between EFS and what package.json declares is invisible at build time

Branch model

From the commit history: branches like uat_des_app and main exist. The git log shows merges from main into uat_des_app (6b1ae7c Merge branch 'main' of https://github.com/Someli-ai/Someli-Designer into uat_des_app) — interesting reverse direction.

Typical platform pattern: feature → dev_des_app → uat_des_app → main. Verify with the team.

ID Recommendation Effort
D-1 Commit a CI workflow (GitHub Actions modelled after someli-api/.github/workflows/dev-api-deploy.yml) Small
D-2 Document the EFS / start.sh wait time and node_modules update procedure Trivial
D-3 Verify the Puppeteer runtime libs are actually needed in the FE container (suspect over-installed) Small
D-4 Document the deploy mechanism / runbook in this repo Small
D-5 Tag Docker images with the git SHA so rollback is well-defined Small