Walkthrough - revant/xkcd-proxy-monorepo GitHub Wiki
Backend
npm i lerna @nestjs/cli -g
mkdir xkcd-proxy-monorepo
cd xkcd-proxy-monorepo
lerna init -i
cd packages
nest new xkcd-proxy-server
cd xkcd-proxy-server && npm i xkcd --save
code .
Change code
// ... AppService
import * as xkcd from 'xkcd';
// ...
getXkcd(res) {
xkcd(data => res.json(data));
}
// ... AppController,
// note: import Res from nestjs
@Get('xkcd')
xkcd(@Res() res) {
this.appService.getXkcd(res);
}
// ... main.ts
await app.listen(8000);
Run Tests and Checks
npm run format -- -c
npm run lint
npm run test
npm run test:e2e
Create Docker Entry Point Script (in docker/
directory of xkcd-proxy-server root) and make it executable chmod +x docker-entrypoint.sh
#!/bin/bash
if [ "$1" = 'start' ]; then
su digithinkit -c "node dist/main.js"
fi
exec runuser -u digithinkit "$@"
Place .dockerignore
node_modules
dist
Place Dockerfile
FROM node:latest
# Copy app
COPY . /home/digithinkit/xkcd-proxy
WORKDIR /home/digithinkit/
RUN cd xkcd-proxy \
&& npm install \
&& npm run prestart:prod \
&& rm -fr node_modules \
&& npm install --only=production
FROM node:slim
# Setup docker-entrypoint
COPY docker/docker-entrypoint.sh usr/local/bin/docker-entrypoint.sh
RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
# Add non root user
RUN useradd -ms /bin/bash digithinkit
WORKDIR /home/digithinkit/xkcd-proxy
COPY --from=0 /home/digithinkit/xkcd-proxy .
RUN chown -R digithinkit:digithinkit /home/digithinkit
# set project directory
WORKDIR /home/digithinkit/xkcd-proxy
# Expose port
EXPOSE 8000
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]
Build and try image
cd ../../ # from root of monorepo
docker build -t xkcd-proxy-backend packages/xkcd-proxy-server
docker run --name xkcd_proxy_backend -d -p "8000:8000" xkcd-proxy-backend:latest
Frontend
cd packages # change to monorepo-root/packages
npm i nwb -g
nwb new react-app xkcd-proxy-client
cd xkcd-proxy-client
npm i
npm run test
npm run build
Change App.js
// Edit UI to show result of `GET /xkcd`
Place docker/nginx.conf
upstream nodejs {
server localhost:8000;
}
server {
listen 8080;
server_name localhost;
root /var/www/html;
location ~* ^/(xkcd) {
try_files $uri $uri/ @nodejs;
}
location / {
try_files $uri $uri/ /index.html;
}
location @nodejs {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://nodejs;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Place .dockerignore
node_modules
dist
Place Dockerfile
FROM node:latest
# Copy app
COPY . /home/digithinkit/xkcd-proxy-client
WORKDIR /home/digithinkit/
RUN cd xkcd-proxy-client \
&& npm install \
&& npm run build
FROM nginx:latest
COPY --from=0 /home/digithinkit/xkcd-proxy-client/dist /var/www/html
COPY ./docker/nginx.conf /etc/nginx/conf.d/xkcdproxy.conf
Build and try image
# from monorepo root
docker build -t xkcd-proxy-frontend packages/xkcd-proxy-client
docker run --name xkcd_proxy_frontend -d -p "8080:8080" xkcd-proxy-frontend:latest
Drone Pipe-line
kind: pipeline
name: default
steps:
- name: test-backend
group: tests
image: node:latest
commands:
- cd packages/xkcd-proxy-server
- npm install
- npm run format -- -c
- npm run lint
# Set environment to test
- export NODE_ENV=test
- npm run test
- npm run test:e2e
- name: test-frontend
group: tests
image: node:latest
commands:
- cd packages/xkcd-proxy-client
- npm install
- npm run test
- name: build-backend
image: plugins/docker
settings:
repo: bloomstack/xkcd-proxy-server
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: packages/xkcd-proxy-server/Dockerfile
context: packages/xkcd-proxy-server
tags:
- edge
when:
event:
- push
branch:
- staging
- name: build-frontend
image: plugins/docker
settings:
repo: bloomstack/xkcd-proxy-client
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: packages/xkcd-proxy-client/Dockerfile
context: packages/xkcd-proxy-client
tags:
- edge
when:
event:
- push
branch:
- staging