Skip to content

Commit

Permalink
feat: prod docker build. (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
morganney authored Dec 14, 2023
1 parent e77efce commit 14950f0
Show file tree
Hide file tree
Showing 18 changed files with 155 additions and 120 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
Dockerfile
coverage
stats.html
npm-debug.log
.env
.github
.git
.gitignore
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ jobs:
BM_POSTGRES_DB: ${{ secrets.BM_POSTGRES_DB }}
SSO_GOOG_CLIENT_ID: ${{ secrets.SSO_GOOG_CLIENT_ID }}
SSO_GOOG_CLIENT_SECRET: ${{ secrets.SSO_GOOG_CLIENT_SECRET }}
run: docker compose build
run: docker compose -f compose.yaml -f compose.production.yaml build stage
- name: Build Components
run: npm run build -w @busmap/components
- name: Build Common
run: npm run build -w @busmap/common
- name: Build API
run: npm run build -w api
- name: Build UI
run: npm run build -w ui
41 changes: 28 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,43 @@ EXPOSE 5432
FROM redis:7.2.3 AS redis
EXPOSE 6739

FROM node:20.10-bookworm-slim AS busmap
FROM node:20.10-bookworm AS builder
ARG VITE_GOOG_CLIENT_ID
WORKDIR /app
COPY package-lock.json package.json .
COPY packages/api/package.json /app/packages/api/package.json
COPY packages/ui/package.json /app/packages/ui/package.json
COPY packages/components/package.json /app/packages/components/package.json
COPY packages/common/package.json /app/packages/common/package.json
COPY . .
RUN npm config set registry https://registry.npmjs.org/
RUN npm install
EXPOSE 3000 5173 9000

FROM busmap AS uibuild
WORKDIR /app
COPY . .
RUN npm run build -w @busmap/components
RUN npm run build -w @busmap/common
RUN npm run build -w api
RUN npm run build -w ui
EXPOSE 3000 5173 9000

FROM nginx:1.25.3 as stage
FROM node:20.10-bookworm-slim AS busmap
WORKDIR /app
COPY --chown=node:node --from=builder /app/package.json package.json
COPY --chown=node:node --from=builder /app/package-lock.json package-lock.json
COPY --chown=node:node --from=builder /app/packages/api/dist packages/api/dist
COPY --chown=node:node --from=builder /app/packages/api/package.json packages/api/package.json
COPY --chown=node:node --from=builder /app/packages/common/package.json packages/common/package.json
RUN npm install --package-lock-only && npm ci --omit=dev
EXPOSE 3000

FROM nginx:1.25.3 as web
ARG HOST_NAME=busmap.localhost
COPY packages/web/certs/ /etc/nginx/certs/
COPY packages/web/conf.d/core/ /etc/nginx/conf.d/core/
COPY packages/web/templates/ /etc/nginx/templates/
COPY packages/web/nginx.conf /etc/nginx/nginx.conf
COPY --from=uibuild /app/packages/ui/dist /var/www/${HOST_NAME}
COPY --from=builder /app/packages/ui/dist /var/www/${HOST_NAME}
EXPOSE 80 443

FROM nginx:1.25.3 AS dev
COPY packages/web/certs/ /etc/nginx/certs/
COPY packages/web/conf.d/core/ /etc/nginx/conf.d/core/
COPY packages/web/default.dev.conf /etc/nginx/conf.d/default.conf
COPY packages/web/nginx.dev.conf /etc/nginx/nginx.conf
EXPOSE 80 443

FROM adminer:4.8.1 as adminer
EXPOSE 8080
7 changes: 0 additions & 7 deletions Dockerfile.override

This file was deleted.

27 changes: 11 additions & 16 deletions compose.override.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ services:
- db
build:
context: .
dockerfile: Dockerfile.override
target: adminer
container_name: adminer
ports:
- "8080:8080"
api:
build:
target: builder
image: busmap-api_dev
container_name: api_dev
ports:
- "3000:3000"
volumes:
- ./packages/api:/app/packages/api
command:
- npm
- run
Expand All @@ -23,14 +28,11 @@ services:
- api
build:
context: .
target: busmap
target: builder
container_name: ui
volumes:
- .:/app
- hoisted_node_modules:/app/node_modules
- common_node_modules:/app/packages/common/node_modules
- ui_node_modules:/app/packages/ui/node_modules
- components_node_modules:/app/packages/components/node_modules
- ./packages/ui:/app/packages/ui
- ./.env:/app/.env # used to inject VITE_ env vars
ports:
- "5173:5173"
environment:
Expand All @@ -44,12 +46,10 @@ services:
storybook:
build:
context: .
target: busmap
target: builder
container_name: storybook
volumes:
- .:/app
- hoisted_node_modules:/app/node_modules
- components_node_modules:/app/packages/components/node_modules
- ./packages/components:/app/packages/components
ports:
- "9000:9000"
command:
Expand All @@ -63,7 +63,6 @@ services:
- ui
build:
context: .
dockerfile: Dockerfile.override
target: dev
container_name: dev
ports:
Expand All @@ -72,7 +71,3 @@ services:
stage:
volumes:
- ./packages/ui/dist:/var/www/${HOST_NAME}

volumes:
ui_node_modules:
components_node_modules:
12 changes: 12 additions & 0 deletions compose.production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
db:
restart: always
session:
restart: always
api:
restart: always
environment:
NODE_ENV: production
DEBUG: ""
stage:
restart: always
22 changes: 8 additions & 14 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,27 @@ services:
depends_on:
- db
- session
init: true
user: node
build:
context: .
target: busmap
args:
VITE_GOOG_CLIENT_ID: ${SSO_GOOG_CLIENT_ID:?err}
container_name: api
volumes:
- .:/app
- hoisted_node_modules:/app/node_modules
- common_node_modules:/app/packages/common/node_modules
- api_node_modules:/app/packages/api/node_modules
env_file: ./packages/api/.env
command:
- npm
- run
- start
- -w
- api
- node
- packages/api/dist/index.js
stage:
depends_on:
- api
build:
context: .
target: stage
target: web
args:
HOST_NAME: ${HOST_NAME}
VITE_GOOG_CLIENT_ID: ${SSO_GOOG_CLIENT_ID:?err}
container_name: stage
ports:
- "80:80"
Expand All @@ -60,6 +57,3 @@ services:
volumes:
db:
session:
hoisted_node_modules:
api_node_modules:
common_node_modules:
3 changes: 2 additions & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
"prettier": "prettier -w .",
"lint": "eslint . src --ext .ts,.tsx --max-warnings 0",
"lint:fix": "npm run lint -- --fix",
"start": "tsx src/index.ts",
"start": "node dist/index.js",
"dev": "tsx --watch src/index.ts",
"dev:local": "tsx --watch --env-file ../../.env src/index.ts",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/handlers/authn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const authn = {
const client = new OAuth2Client()
let payload: TokenPayload | undefined

debug('verifying id token with goog client id', env.SSO_GOOG_CLIENT_ID)
try {
const ticket = await client.verifyIdToken({
idToken: req.body.credential,
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const debug = makeDebug('busmap')
const app = express()

if (env.BM_SESSION_STORE === 'redis') {
debug('initializing redis store')
debug('initializing redis store at host', env.BM_REDIS_HOST)
const client = createClient({ url: env.BM_REDIS_HOST })

try {
Expand Down
5 changes: 5 additions & 0 deletions packages/api/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"noEmit": false
},
"include": ["src"]
}
2 changes: 1 addition & 1 deletion packages/ui/src/components/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const Profile: FC = () => {
}
}, [dispatch, dispatchStorage])
const onClickDisconnect = useCallback(() => {
if (user) {
if (user && google) {
// TODO: Do not logout. Instead open modal explaining they will need to re-connect next sign in.
google.accounts.id.revoke(user.sub, async resp => {
if (resp.error) {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/modules/favorites/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const getFavoritePreds = async (timeSinceLastFetch: number) => {
}
}

cancelAnimationFrame(timeoutId)
timeoutId = requestAnimationFrame(getFavoritePreds)
}
const restartFavoritesPoll = debounce(
Expand Down
2 changes: 2 additions & 0 deletions packages/web/conf.d/core/upstreams.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# DNS resolution works at startup via `depends_on` for `web` service in compose.yaml.
upstream api_server {
server api:3000;

keepalive 2;
}
34 changes: 34 additions & 0 deletions packages/web/default.dev.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
server {
# Redirect server configuration
listen 80 default_server;
server_name busmap.localhost localhost;
server_tokens off;

location / {
return 301 https://$host$request_uri;
}
}

server {
listen 80;
listen 443 ssl;
server_name busmap.localhost localhost;
index index.html;

ssl_certificate /etc/nginx/certs/busmap.localhost.pem;
ssl_certificate_key /etc/nginx/certs/busmap.localhost-key.pem;
include /etc/nginx/conf.d/core/compression.conf;

location / {
resolver 8.8.8.8 valid=30s;

proxy_pass http://dev_server;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
34 changes: 34 additions & 0 deletions packages/web/nginx.dev.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
# For mapping Connection header to presence of Upgrade header to support HMR websockets.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

# DNS resolution works at startup via `depends_on` for `web` service in docker-compose.yml.
upstream dev_server {
server ui:5173;
}

include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$request_method $request_uri $status $body_bytes_sent - $request_time s';

access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;

include /etc/nginx/conf.d/core/upstreams.conf;
include /etc/nginx/conf.d/core/logging.conf;
# The config for the defined server(s)
include /etc/nginx/conf.d/*.conf;
}
Loading

0 comments on commit 14950f0

Please sign in to comment.