Skip to content

Commit

Permalink
feat: rewrite to use only nginx (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
samialdury authored Aug 29, 2023
1 parent 387008e commit 1bc77aa
Show file tree
Hide file tree
Showing 30 changed files with 1,056 additions and 2,278 deletions.
6 changes: 0 additions & 6 deletions .example.env

This file was deleted.

2 changes: 0 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ jobs:
push: true
provenance: false
build-args: |
NODE_VERSION=${{ env.NODE_VERSION }}
PNPM_VERSION=${{ env.PNPM_VERSION }}
COMMIT_SHA=${{ steps.git-meta.outputs.BRANCH_OR_TAG_NORMALIZED_WITH_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ jobs:
push: true
provenance: false
build-args: |
NODE_VERSION=${{ env.NODE_VERSION }}
PNPM_VERSION=${{ env.PNPM_VERSION }}
COMMIT_SHA=${{ steps.git-meta.outputs.BRANCH_OR_TAG_NORMALIZED_WITH_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ coverage
cache
.husky
pnpm-lock.yaml
*.md
101 changes: 13 additions & 88 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,92 +1,17 @@
ARG NODE_VERSION=18
ARG PNPM_VERSION=8
ARG TINI_VERSION="v0.19.0"
ARG COMMIT_SHA="unknown"

################################################################
# #
# Prepare alpine image #
# #
################################################################

FROM node:${NODE_VERSION}-alpine as node-alpine

ARG PNPM_VERSION
ARG TINI_VERSION

ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini

RUN chmod +x /tini
RUN apk --no-cache add curl
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
RUN npm install --global pnpm@${PNPM_VERSION}

################################################################
# #
# Prepare distroless image #
# #
################################################################

FROM gcr.io/distroless/nodejs${NODE_VERSION}-debian11:nonroot as node-distroless

################################################################
# #
# Install all dependencies and build TypeScript #
# #
################################################################

FROM node-alpine as build-js

COPY package.json package.json
COPY pnpm-lock.yaml pnpm-lock.yaml

RUN pnpm fetch

COPY tsconfig.base.json tsconfig.base.json
COPY tsconfig.prod.json tsconfig.prod.json
COPY src src
FROM nginx:1-alpine

RUN pnpm install --offline --frozen-lockfile
RUN ./node_modules/.bin/tsc --project ./tsconfig.prod.json

################################################################
# #
# Install only production dependencies & prune unused files #
# #
################################################################

FROM node-alpine as install-prod-deps

ENV NODE_ENV="production"

COPY --from=build-js package.json package.json
COPY --from=build-js pnpm-lock.yaml pnpm-lock.yaml

RUN pnpm fetch
RUN pnpm install --offline --frozen-lockfile --prod
RUN node-prune

################################################################
# #
# Copy only necessary data for runtime #
# #
################################################################

FROM node-distroless as final
ARG COMMIT_SHA="unknown"

ARG COMMIT_SHA
COPY ./nginx/templates /etc/nginx/templates

ENV NODE_OPTIONS="--enable-source-maps --dns-result-order=ipv4first"
ENV NODE_ENV="production"
ENV COMMIT_SHA=${COMMIT_SHA}

COPY --from=node-alpine --chown=nonroot:nonroot /tini /tini
COPY --from=build-js --chown=nonroot:nonroot package.json package.json
COPY --from=build-js --chown=nonroot:nonroot build build
COPY --from=install-prod-deps --chown=nonroot:nonroot node_modules node_modules

USER nonroot:nonroot

ENTRYPOINT ["/tini", "--"]

CMD ["/nodejs/bin/node", "./build/src/main.js"]
ENV PROXY_PORT=8000
ENV CLIENT_MAX_BODY_SIZE=20m
ENV ERROR_LOG_LEVEL=error
ENV WEB_SDK_HOST=web-sdk.smartlook.com
ENV MANAGER_HOST=manager.eu.smartlook.cloud
ENV ASSETS_PROXY_HOST=assets-proxy.smartlook.cloud
ENV WEB_SDK_WRITER_HOST=web-writer.eu.smartlook.cloud
ENV MOBILE_SDK_WRITER_HOST=sdk-writer.eu.smartlook.cloud

EXPOSE ${PROXY_PORT}
48 changes: 14 additions & 34 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
PROJECT_NAME := smartlook-relay-proxy
COMMIT_SHA := dev,$(shell git rev-parse HEAD)

NPM_BIN := ./node_modules/.bin

TSC := $(NPM_BIN)/tsc
TSX := $(NPM_BIN)/tsx
VITEST := $(NPM_BIN)/vitest
PRETTIER := $(NPM_BIN)/prettier
ESLINT := $(NPM_BIN)/eslint
PINO_PRETTY := $(NPM_BIN)/pino-pretty
HUSKY := $(NPM_BIN)/husky

COMMIT_SHA := dev,$(shell git rev-parse HEAD)
ESLINT_CACHE := ./cache/eslint
PRETTIER_CACHE := ./cache/prettier

ESLINT_CACHE := ./cache/.eslintcache
PRETTIER_CACHE := ./cache/.prettiercache
COMPOSE_TEST_CMD := docker compose up -d --build --force-recreate --remove-orphans && sleep 5

.PHONY: help
## Display this help
Expand All @@ -22,49 +20,32 @@ help:

##@ Development

.PHONY: install
install: ## install all dependencies
pnpm install
$(HUSKY) install

.PHONY: dev
dev: ## run TS (watch mode)
COMMIT_SHA="$(COMMIT_SHA)" $(TSX) watch --clear-screen=false -r dotenv/config ./src/main.ts | $(PINO_PRETTY)

.PHONY: run-js
run-js: ## run built JS
node -r dotenv/config ./build/src/main.js
docker compose up

##@ Build

.PHONY: build
build: ## build TS
rm -rf ./build
$(TSC) --build --force

.PHONY: build-prod
build-prod: ## build TS (for production)
rm -rf ./build
$(TSC) --project ./tsconfig.prod.json
.PHONY: build-ts
build-ts: ## build TS
$(TSC) --noEmit

.PHONY: build-image
build-image: ## build Docker image (args=<build args>, tag=<string>)
.PHONY: build
build: ## build Docker image (args=<build args>, tag=<string>)
docker build $(or $(args), --build-arg COMMIT_SHA="$(COMMIT_SHA)") -t $(or $(tag), $(PROJECT_NAME)) . -f ./Dockerfile

##@ Test

.PHONY: test
test: ## run tests
$(COMPOSE_TEST_CMD)
$(VITEST) run

.PHONY: test-watch
test-watch: ## run tests (watch mode)
$(COMPOSE_TEST_CMD)
$(VITEST) watch

.PHONY: test-coverage
test-coverage: ## run tests (with coverage)
$(VITEST) run --coverage

##@ Code quality

.PHONY: prettier
Expand All @@ -85,11 +66,10 @@ install-ci: ## install all dependencies (CI)
pnpm install --frozen-lockfile

.PHONY: build-ci
build-ci: ## build TS (CI)
$(TSC) --build --force
build-ci: build-ts ## build TS (CI)

.PHONY: test-ci
test-ci: test-coverage ## run tests (CI)
test-ci: test ## run tests (CI)

.PHONY: prettier-ci
prettier-ci: ## run Prettier (CI)
Expand Down
43 changes: 21 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,27 @@ You have now installed and deployed the Smartlook relay proxy. You can check if

## Environment variables

| Name | Type | Default value | Description | Notes |
| --------------------- | --------- | --------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `LOGGER_LEVEL` | `string` | `info` | One of `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` | Can be overridden |
| `PROXY_PORT` | `number` | `8000` | Port which will the HTTP server listen on | Can be overridden |
| `WEB_SDK_HOST` | `string` | `https://web-sdk.smartlook.com` | Smartlook Web SDK host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `MANAGER_HOST` | `string` | `https://manager.eu.smartlook.cloud` | Smartlook Manager host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `WEB_SDK_WRITER_HOST` | `string` | `https://web-writer.eu.smartlook.cloud` | Smartlook Web Writer host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `ASSETS_PROXY_HOST` | `string` | `https://assets-proxy.smartlook.cloud` | Smartlook Assets Proxy host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `LOG_REQUESTS` | `boolean` | `false` | Log all requests (useful for debugging) | |
| `TRUST_PROXY` | `boolean` | `true` | See Fastify's [trustProxy](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy) option | |
| Name | Type | Default value | Description | Notes |
| --------------------- | -------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `ERROR_LOG_LEVEL` | `string` | `error` | [Nginx error log level](https://nginx.org/en/docs/ngx_core_module.html#error_log). One of `debug`, `info`, `notice`, `warn`, `error`, `crit`, `alert`, `emerg`. | Can be overridden |
| `CLIENT_MAX_BODY_SIZE` | `string` | `20m` | [Nginx client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). | Can be overridden |
| `PROXY_PORT` | `number` | `8000` | Port which will the HTTP server listen on | Can be overridden |
| `WEB_SDK_HOST` | `string` | `web-sdk.smartlook.com` | Smartlook Web SDK host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `MANAGER_HOST` | `string` | `manager.eu.smartlook.cloud` | Smartlook Manager host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `WEB_SDK_WRITER_HOST` | `string` | `web-writer.eu.smartlook.cloud` | Smartlook Web Writer host | Only edit this value if using a region other than EU, or if instructed by customer support |
| `ASSETS_PROXY_HOST` | `string` | `assets-proxy.smartlook.cloud` | Smartlook Assets Proxy host | Only edit this value if using a region other than EU, or if instructed by customer support |

## Regional setup

Smartlook offers two regions for data storage: EU and US. By default, all projects are set to the EU region. To change your data storage region, contact Smartlook Support.

If your project is set to the US data region, you need to set the variables as follows:

| Name | Value |
| --------------------- | ----------------------------------------- |
| `MANAGER_HOST` | `https://manager.us.smartlook.cloud` |
| `WEB_SDK_WRITER_HOST` | `https://web-writer.us.smartlook.cloud` |
| `ASSETS_PROXY_HOST` | `https://assets-proxy.us.smartlook.cloud` |
| Name | Value |
| --------------------- | --------------------------------- |
| `MANAGER_HOST` | `manager.us.smartlook.cloud` |
| `WEB_SDK_WRITER_HOST` | `web-writer.us.smartlook.cloud` |
| `ASSETS_PROXY_HOST` | `assets-proxy.us.smartlook.cloud` |

If most of your visitors are located in a different region, you can set environment variables to reduce network latency. Smartlook servers are located in four regions:

Expand All @@ -91,20 +90,20 @@ To set up for other regions:
> **Note**
> For this region, only the `WEB_SDK_WRITER_HOST` is available.
| Name | Value |
| --------------------- | --------------------------------------- |
| `WEB_SDK_WRITER_HOST` | `https://web-writer.br.smartlook.cloud` |
| Name | Value |
| --------------------- | ------------------------------- |
| `WEB_SDK_WRITER_HOST` | `web-writer.br.smartlook.cloud` |

#### Asia

> **Note**
> For this region, only the `WEB_SDK_WRITER_HOST` is available.
| Name | Value |
| --------------------- | --------------------------------------- |
| `WEB_SDK_WRITER_HOST` | `https://web-writer.sg.smartlook.cloud` |
| Name | Value |
| --------------------- | ------------------------------- |
| `WEB_SDK_WRITER_HOST` | `web-writer.sg.smartlook.cloud` |

**By default, all data is stored in the EU**. However, if your Smartlook organization is set up to store data in US (you must contact Smartlook support to set it up), you need to set the environment variables as described in region-specific setup [above](#north-america).
**By default, all data is stored in the EU**. However, if your Smartlook organization is set up to store data in US (you must contact Smartlook support to set it up), you need to set the environment variables as described in region-specific setup [above](#regional-setup).

## Development

Expand Down
18 changes: 0 additions & 18 deletions docker-compose.dev.yml

This file was deleted.

25 changes: 25 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: '3'

services:
nginx:
image: nginx:1-alpine
container_name: nginx
restart: unless-stopped
ports:
- 80:8000
environment:
COMMIT_SHA: dev
PROXY_PORT: 8000
CLIENT_MAX_BODY_SIZE: 20m
ERROR_LOG_LEVEL: error
WEB_SDK_HOST: web-sdk.smartlook.com
MANAGER_HOST: manager.eu.smartlook.cloud
ASSETS_PROXY_HOST: assets-proxy.smartlook.cloud
WEB_SDK_WRITER_HOST: web-writer.eu.smartlook.cloud
MOBILE_SDK_WRITER_HOST: sdk-writer.eu.smartlook.cloud
volumes:
- ./nginx/templates:/etc/nginx/templates
- nginx_data:/etc/nginx

volumes:
nginx_data:
2 changes: 1 addition & 1 deletion lint-staged.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function toRelative(file) {
async function removeIgnoredFiles(files) {
const eslint = new ESLint()
const isIgnored = await Promise.all(
files.map((file) => eslint.isPathIgnored(file))
files.map((file) => eslint.isPathIgnored(file)),
)
const filteredFiles = files.filter((_, i) => !isIgnored[i])
return filteredFiles
Expand Down
Loading

0 comments on commit 1bc77aa

Please sign in to comment.