prod.Dockerfile 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # This step is used to build a custom build of Caddy to prevent
  2. # vulnerable packages on the dependency chain
  3. FROM alpine:3.21.2 AS caddy_builder
  4. RUN apk add curl go
  5. RUN mkdir -p /tmp/caddy-build
  6. RUN curl -L -o /tmp/caddy-build/src.tar.gz https://github.com/caddyserver/caddy/releases/download/v2.9.1/caddy_2.9.1_src.tar.gz
  7. # Checksum verification of caddy source
  8. RUN expected="1cfd6127f9ed8dc908d84d7d14579d3ce5114e8671aa8f786745cb3fe60923e0" && \
  9. actual=$(sha256sum /tmp/caddy-build/src.tar.gz | cut -d' ' -f1) && \
  10. [ "$actual" = "$expected" ] && \
  11. echo "✅ Caddy Source Checksum OK" || \
  12. (echo "❌ Caddy Source Checksum failed!" && exit 1)
  13. WORKDIR /tmp/caddy-build
  14. RUN tar xvf /tmp/caddy-build/src.tar.gz
  15. # Patch to resolve CVE-2024-45339 on glog
  16. RUN go get github.com/golang/glog@v1.2.4
  17. # Patch to resolve CVE-2025-2714 on go-jose
  18. RUN go get github.com/go-jose/go-jose/v3@v3.0.4
  19. # Patch to resolve CVE-2025-22869 on crypto
  20. RUN go get golang.org/x/crypto@v0.35.0
  21. RUN go mod vendor
  22. WORKDIR /tmp/caddy-build/cmd/caddy
  23. RUN go build
  24. FROM alpine:3.19.7 AS base_builder
  25. RUN apk add nodejs curl
  26. # Install NPM from source, as Alpine version is old and has dependency vulnerabilities
  27. # TODO: Find a better method which is resistant to supply chain attacks
  28. RUN sh -c "curl -qL https://www.npmjs.com/install.sh | env npm_install=10.9.2 sh"
  29. WORKDIR /usr/src/app
  30. ENV HOPP_ALLOW_RUNTIME_ENV=true
  31. # Required by @hoppscotch/js-sandbox to build `isolated-vm`
  32. RUN apk add python3 make g++ zlib-dev brotli-dev c-ares-dev nghttp2-dev openssl-dev icu-dev
  33. RUN npm install -g pnpm@10.2.1
  34. COPY pnpm-lock.yaml .
  35. RUN pnpm fetch
  36. COPY . .
  37. RUN pnpm install -f --prefer-offline
  38. FROM base_builder AS backend_builder
  39. WORKDIR /usr/src/app/packages/hoppscotch-backend
  40. RUN pnpm exec prisma generate
  41. RUN pnpm run build
  42. RUN pnpm --filter=hoppscotch-backend deploy /dist/backend --prod --legacy
  43. WORKDIR /dist/backend
  44. RUN pnpm exec prisma generate
  45. FROM alpine:3.19.7 AS backend
  46. RUN apk add nodejs curl
  47. # Install NPM from source, as Alpine version is old and has dependency vulnerabilities
  48. # TODO: Find a better method which is resistant to supply chain attacks
  49. RUN sh -c "curl -qL https://www.npmjs.com/install.sh | env npm_install=10.9.2 sh"
  50. # Install caddy
  51. COPY --from=caddy_builder /tmp/caddy-build/cmd/caddy/caddy /usr/bin/caddy
  52. RUN npm install -g pnpm@10.2.1
  53. COPY --from=base_builder /usr/src/app/packages/hoppscotch-backend/backend.Caddyfile /etc/caddy/backend.Caddyfile
  54. COPY --from=backend_builder /dist/backend /dist/backend
  55. COPY --from=base_builder /usr/src/app/packages/hoppscotch-backend/prod_run.mjs /dist/backend
  56. # Remove the env file to avoid backend copying it in and using it
  57. ENV PRODUCTION="true"
  58. ENV PORT=8080
  59. ENV APP_PORT=${PORT}
  60. ENV DB_URL=${DATABASE_URL}
  61. WORKDIR /dist/backend
  62. CMD ["node", "prod_run.mjs"]
  63. EXPOSE 80
  64. EXPOSE 3170
  65. FROM base_builder AS fe_builder
  66. WORKDIR /usr/src/app/packages/hoppscotch-selfhost-web
  67. RUN pnpm run generate
  68. FROM rust:1-alpine AS webapp_server_builder
  69. WORKDIR /usr/src/app
  70. RUN apk add --no-cache musl-dev
  71. COPY . .
  72. WORKDIR /usr/src/app/packages/hoppscotch-selfhost-web/webapp-server
  73. RUN cargo build --release
  74. FROM alpine:3.19.7 AS app
  75. RUN apk add nodejs curl
  76. # Install NPM from source, as Alpine version is old and has dependency vulnerabilities
  77. # TODO: Find a better method which is resistant to supply chain attacks
  78. RUN sh -c "curl -qL https://www.npmjs.com/install.sh | env npm_install=10.9.2 sh"
  79. # Install caddy
  80. COPY --from=caddy_builder /tmp/caddy-build/cmd/caddy/caddy /usr/bin/caddy
  81. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/prod_run.mjs /site/prod_run.mjs
  82. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/selfhost-web.Caddyfile /etc/caddy/selfhost-web.Caddyfile
  83. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/dist/ /site/selfhost-web
  84. RUN npm install -g @import-meta-env/cli
  85. EXPOSE 80
  86. EXPOSE 3000
  87. WORKDIR /site
  88. CMD ["/bin/sh", "-c", "node /site/prod_run.mjs && caddy run --config /etc/caddy/selfhost-web.Caddyfile --adapter caddyfile"]
  89. FROM base_builder AS sh_admin_builder
  90. WORKDIR /usr/src/app/packages/hoppscotch-sh-admin
  91. # Generate two builds for `sh-admin`, one based on subpath-access and the regular build
  92. RUN pnpm run build --outDir dist-multiport-setup
  93. RUN pnpm run build --outDir dist-subpath-access --base /admin/
  94. FROM alpine:3.19.7 AS sh_admin
  95. RUN apk add nodejs curl
  96. # Install NPM from source, as Alpine version is old and has dependency vulnerabilities
  97. # TODO: Find a better method which is resistant to supply chain attacks
  98. RUN sh -c "curl -qL https://www.npmjs.com/install.sh | env npm_install=10.9.2 sh"
  99. # Install caddy
  100. COPY --from=caddy_builder /tmp/caddy-build/cmd/caddy/caddy /usr/bin/caddy
  101. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/prod_run.mjs /site/prod_run.mjs
  102. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/sh-admin-multiport-setup.Caddyfile /etc/caddy/sh-admin-multiport-setup.Caddyfile
  103. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/sh-admin-subpath-access.Caddyfile /etc/caddy/sh-admin-subpath-access.Caddyfile
  104. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/dist-multiport-setup /site/sh-admin-multiport-setup
  105. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/dist-subpath-access /site/sh-admin-subpath-access
  106. RUN npm install -g @import-meta-env/cli
  107. EXPOSE 80
  108. EXPOSE 3100
  109. WORKDIR /site
  110. CMD ["node","/site/prod_run.mjs"]
  111. FROM node:20-alpine AS webapp_server
  112. COPY --from=webapp_server_builder /usr/src/app/packages/hoppscotch-selfhost-web/webapp-server/target/release/webapp-server /usr/local/bin/
  113. RUN mkdir -p /site/selfhost-web
  114. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/dist /site/selfhost-web
  115. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/prod_run.mjs /site/prod_run.mjs
  116. RUN apk add nodejs npm
  117. RUN npm install -g @import-meta-env/cli
  118. WORKDIR /site
  119. CMD ["/bin/sh", "-c", "node /site/prod_run.mjs && webapp-server"]
  120. EXPOSE 3200
  121. FROM alpine:3.19.7 AS aio
  122. RUN apk add nodejs curl
  123. # Install NPM from source, as Alpine version is old and has dependency vulnerabilities
  124. # TODO: Find a better method which is resistant to supply chain attacks
  125. RUN sh -c "curl -qL https://www.npmjs.com/install.sh | env npm_install=10.9.2 sh"
  126. # Caddy install
  127. COPY --from=caddy_builder /tmp/caddy-build/cmd/caddy/caddy /usr/bin/caddy
  128. ENV PRODUCTION="true"
  129. ENV PORT=8080
  130. ENV APP_PORT=${PORT}
  131. ENV DB_URL=${DATABASE_URL}
  132. # Open Containers Initiative (OCI) labels - useful for bots like Renovate
  133. LABEL org.opencontainers.image.source="https://github.com/hoppscotch/hoppscotch" \
  134. org.opencontainers.image.url="https://docs.hoppscotch.io" \
  135. org.opencontainers.image.licenses="MIT"
  136. RUN apk add tini
  137. RUN npm install -g pnpm@10.2.1
  138. # Copy necessary files
  139. # Backend files
  140. COPY --from=base_builder /usr/src/app/packages/hoppscotch-backend/backend.Caddyfile /etc/caddy/backend.Caddyfile
  141. COPY --from=backend_builder /dist/backend /dist/backend
  142. COPY --from=base_builder /usr/src/app/packages/hoppscotch-backend/prod_run.mjs /dist/backend
  143. # Static Server
  144. COPY --from=webapp_server_builder /usr/src/app/packages/hoppscotch-selfhost-web/webapp-server/target/release/webapp-server /usr/local/bin/
  145. RUN mkdir -p /site/selfhost-web
  146. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/dist /site/selfhost-web
  147. # FE Files
  148. COPY --from=base_builder /usr/src/app/aio_run.mjs /usr/src/app/aio_run.mjs
  149. COPY --from=fe_builder /usr/src/app/packages/hoppscotch-selfhost-web/dist /site/selfhost-web
  150. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/dist-multiport-setup /site/sh-admin-multiport-setup
  151. COPY --from=sh_admin_builder /usr/src/app/packages/hoppscotch-sh-admin/dist-subpath-access /site/sh-admin-subpath-access
  152. COPY aio-multiport-setup.Caddyfile /etc/caddy/aio-multiport-setup.Caddyfile
  153. COPY aio-subpath-access.Caddyfile /etc/caddy/aio-subpath-access.Caddyfile
  154. RUN npm install -g @import-meta-env/cli
  155. ENTRYPOINT [ "tini", "--" ]
  156. COPY --chmod=755 healthcheck.sh /
  157. HEALTHCHECK --interval=2s CMD /bin/sh /healthcheck.sh
  158. WORKDIR /dist/backend
  159. CMD ["node", "/usr/src/app/aio_run.mjs"]
  160. # NOTE: Although these ports are exposed, the HOPP_ALTERNATE_AIO_PORT variable can be used to assign a user-specified port
  161. EXPOSE 3170
  162. EXPOSE 3000
  163. EXPOSE 3100
  164. EXPOSE 3200
  165. EXPOSE 80