# Sysmaker Docker Support ###### tags: `Sysmaker` `Docker` `Dockerfile` `docker-compose` [TOC] ## About Sysmaker * We ars **Sysmaker team** from *EPL, NTHU* * Find us [**`@Sysmaker.Org`**](https://sysmaker.org) & [**`@Sysmaker GitHub`**](https://github.com/sysmaker-org) + We haven't published our source code yet + However, our production docker images are available @[**Docker Hub**](https://hub.docker.com/u/sysmaker) ## About Docker > **`TL;DR`** **Visit Sysmaker [*`GitHub Repo`*](https://github.com/Sysmaker-Org/Docker) to trace our code** [color=red] * Run Sysmaker (refer @[`GitHub`](https://github.com/Sysmaker-Org/Sysmaker-Docker_Images#run) for further info) 1. `$ ./1-up.sh` (sysmaker/syamker-app & api) 2. `$ ./1-up.sh single` (sysmaker/sysmaker) * The docker image categories we are offering now *(Apr 2020 ~)* + There are stable **`master`** branch and developing **`feature`** branch in our workflow + **`Image for Mainline`** :::success 1. **`:master-*`**: the **testing passed** versions 2. **`:latest`**: the newest *`master-`* version 3. **`:prod`**: the newest *stable `master-` version* for mid-term production 4. **`:vXX.YY.ZZ`**: the *stable `prod` versions* which *deserve version tags* :D ::: + **`Image under Development`** :::info 1. **`:dev`**: the newest *`feature-`* version (specific feature image is NOT provided) ::: - :::warning * <span style="color:red">**`sysmaker/sysmaker-env`** use **`:latest`** for both *`master-*`* and *`feature-*`* branches</span> (but still having `:dev`) + This is by design for GitLab CI so that we can always use the `latest` tag even when we're on the `feature branch` + Use **`master-*`** tags to make sure you're using the correct environment ::: * In order to make use of our images, some `docker-compose*.yml`, `Dockerfile*`, and `*.conf` are provided as follows + *Dockerfile* 1. [**`sysmaker/sysmaker-env`**](#sysmakersysmaker-env) 2. [**`the rest`**](#sysmakersysmaker-sysmakersysmaker-app-and-sysmakersysmaker-api) + *docker-compose.yml* 1. [**`environment variables`**](#env) 2. [**`sysmaker/sysmaker (single)`**](#sysmakersysmaker-single) 3. [**`sysmaker/sysmaker-app&api (normal)`**](#sysmakersysmaker-app-and-sysmakersysmaker-api-normal) + *(Nginx) Configs* 1. [**`Angular (sysmaker-app)`**](#appconf) 2. [**`Sysmaker normal (APP + API + Nginx)`**](#normalhttpsconf) 3. [**`Sysmaker single`**](#singlehttpsconf) 4. [**`Cloudflare Proxy IP Restore`**](#restore-ipcloudflare) * *CHANGELOG* + **`master-0012-4045ddb`~ `now`** [time=Apr 2, 2020] [color=red] * Folder structure + ```bash= ├── 0-build.sh ├── 1-up.sh ├── 2-down.sh ├── 3-push.sh │ ├── .docker-compose.env.yml # for `sysmaker/sysmaker-env` ├── .Dockerfile-env ├── .env # specify base image versions │ ├── docker-compose.gitlab-ci.yml # for GitLab CI to build images ├── docker-compose.single.yml # single ├── docker-compose.yml # app and api (normal) ├── Dockerfile │ └── misc ├── nginx-confd │ ├── app.conf # for Nginx to serve Angular │ ├── nginx.http.conf # just remove `https` part │ ├── nginx.https.conf │ ├── single.http.conf │ └── single.https.conf │ └── ssl ├── restore-ip.cloudflare ├── sysmaker.crt # Use your own SSL certificate └── sysmaker.key # Ibid. ``` ### Dockerfile > `master-0012-4045ddb` ~ `now` #### [**`sysmaker/sysmaker-env`**](https://github.com/Sysmaker-Org/Docker/blob/master/.Dockerfile-env) ```dockerfile= ARG IMAGE_CYPRESS=cypress/base:12.16.1 FROM $IMAGE_CYPRESS LABEL maintainer="LouisSung <ls@sysmaker.org>" \ description="Sysmaker environment for ci and build (with Cypress, NPM, and Docker)" ARG IMAGE_CYPRESS WORKDIR /sysmaker COPY sysmaker/package*.json ./ COPY misc/pages/* ./pages/ RUN echo "Image: $IMAGE_CYPRESS" \ && apt-get update && apt-get install -y --no-install-recommends \ bash bc curl jq git rsync tree libcanberra-gtk3-module \ apt-transport-https ca-certificates gnupg2 software-properties-common \ && curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \ && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \ && apt-get update && apt-get install -y --no-install-recommends \ docker-ce=5:19.03.8~3-0~debian-buster docker-ce-cli=5:19.03.8~3-0~debian-buster containerd.io \ && curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \ && chmod +x /usr/local/bin/docker-compose \ && rm -rf /var/lib/apt/lists/* \ \ && npm install --ignore-scripts --no-audit --loglevel info \ && npm audit fix --ignore-scripts --verbose \ && npm run postinstall \ && $(npm bin)/cypress install SHELL ["/bin/bash", "-c"] CMD ["bash", "-c", "exit 0"] ``` #### [**`sysmaker/sysmaker`**, **`sysmaker/sysmaker-app`**, and **`sysmaker/sysmaker-api`**](https://github.com/Sysmaker-Org/Docker/blob/master/.Dockerfile-env) ```dockerfile= # ===== default images ===== ARG IMAGE_SYSMAKER_ENV=sysmaker/sysmaker-env:latest ARG IMAGE_NODE=node:lts-alpine ARG IMAGE_NGINX=nginx:alpine # ===== build stage ===== FROM $IMAGE_SYSMAKER_ENV AS base LABEL sysmaker="build" ARG IMAGE_SYSMAKER_ENV WORKDIR /sysmaker/ COPY sysmaker/ misc/nginx-confd/app.conf ./ RUN echo "Image: $IMAGE_SYSMAKER_ENV" \ && npm run sysmaker:build \ && mv package-lock.json old-package-lock.json && mv node_modules/ old-node_modules/ \ && find dist/apps/sysmaker \( -name '*.js' -o -name '*.css' \) -type f -exec gzip -9 -k "{}" \; \ \ && npm install @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata rxjs tslib \ && cp -r node_modules/ dist/apps/api/ # ===== APP ===== FROM $IMAGE_NGINX AS sysmaker-app LABEL maintainer="LouisSung <ls@sysmaker.org>" \ description="Sysmaker APP" \ sysmaker="app" COPY --from=base /sysmaker/dist/apps/sysmaker/ /usr/share/nginx/html/ COPY --from=base /sysmaker/app.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] # ===== API ===== FROM $IMAGE_NODE AS sysmaker-api LABEL maintainer="LouisSung <ls@sysmaker.org>" \ description="Sysmaker API" \ sysmaker="api" WORKDIR /sysmaker/api/ COPY --from=base /sysmaker/dist/apps/api/ /sysmaker/api/ ENV port=80 EXPOSE 80 CMD ["node", "/sysmaker/api/main.js"] # ===== SINGLE ===== FROM $IMAGE_NODE AS sysmaker-single LABEL maintainer="LouisSung <ls@sysmaker.org>" \ description="Sysmaker" \ sysmaker="single" WORKDIR /sysmaker/ COPY --from=base /sysmaker/dist/apps/sysmaker/ /usr/share/nginx/html/ COPY --from=base /sysmaker/dist/apps/api/ /sysmaker/api/ RUN apk update && apk add --no-cache nginx && mkdir -p /var/run/nginx EXPOSE 80 EXPOSE 443 ENTRYPOINT [] CMD ["sh", "-c", "nginx & nohup node /sysmaker/api/main.js"] ``` ### docker-compose.yml > `master-0012-4045ddb` ~ `now` #### [**`.env`**](https://github.com/Sysmaker-Org/Docker/blob/master/.env) > save as an `.env` file and put in the same folder as `docker-compose.yml` ```bash= # Nginx for APP: Latest + Alpine (https://hub.docker.com/_/nginx?tab=tags&page=1&name=-alpine) VER_NGINX=1.17.9-alpine # Node.js for API: LTS !! + Alpine (https://hub.docker.com/_/node?tab=tags&page=1&name=-alpine) VER_NODE=12.16.1-alpine3.11 # Cypress for CI and build: Sync with Node.js version !! (https://github.com/cypress-io/cypress-docker-images/tree/master/base) VER_CYPRESS=12.16.1 IMAGE_TAG=master-0012-4045ddb ``` #### [**`sysmaker/sysmaker`**](https://github.com/Sysmaker-Org/Docker/blob/master/docker-compose.single.yml) (single) ```yaml= # Single Sysmaker image (APP & API in single image) version: '3.7' # ===== configs ===== x-images: &images IMAGE_NODE: node:${VER_NODE} IMAGE_NGINX: nginx:${VER_NGINX} # IMAGE_SYSMAKER_ENV: sysmaker/sysmaker-env:${IMAGE_TAG} # prefer using Docker Hub latest one x-https: &https - ./misc/nginx-confd/single.https.conf:/etc/nginx/conf.d/default.conf:ro - ./misc/ssl/:/etc/nginx/conf.d/ssl/:ro x-http: &http - ./misc/nginx-confd/single.http.conf:/etc/nginx/conf.d/default.conf:ro - ./misc/ssl/restore-ip.cloudflare:/etc/nginx/conf.d/ssl/restore-ip.cloudflare:ro # ===== services ===== services: sysmaker-single: build: context: . target: sysmaker-single args: *images image: sysmaker/sysmaker:${IMAGE_TAG} container_name: Sysmaker hostname: Sysmaker volumes: *http ports: - '80:80' - '443:443' ``` #### [**`sysmaker/sysmaker-app`** and **`sysmaker/sysmaker-api`**](https://github.com/Sysmaker-Org/Docker/blob/master/docker-compose.yml) (normal) ```yaml= # Normal Sysmaker images (APP + API + Nginx) version: '3.7' # ===== configs ===== x-images: &images IMAGE_NODE: node:${VER_NODE} IMAGE_NGINX: nginx:${VER_NGINX} # IMAGE_SYSMAKER_NPM_OR_NODE: sysmaker/sysmaker-npm:${IMAGE_TAG} # prefer Docker Hub one x-https: &https - ./misc/nginx-confd/normal.https.conf:/etc/nginx/conf.d/default.conf:ro - ./misc/ssl/:/etc/nginx/conf.d/ssl/:ro x-http: &http - ./misc/nginx-confd/normal.http.conf:/etc/nginx/conf.d/default.conf:ro - ./misc/ssl/restore-ip.cloudflare:/etc/nginx/conf.d/ssl/restore-ip.cloudflare:ro # ===== services ===== services: sysmaker-app: build: context: . target: sysmaker-app args: *images image: sysmaker/sysmaker-app:${IMAGE_TAG} container_name: Sysmaker-APP hostname: Sysmaker-APP networks: - sysmaker-lan sysmaker-api: build: context: . target: sysmaker-api args: *images image: sysmaker/sysmaker-api:${IMAGE_TAG} container_name: Sysmaker-API hostname: Sysmaker-API networks: - sysmaker-lan sysmaker-nginx: image: nginx:${VER_NGINX} container_name: Sysmaker-Nginx hostname: Sysmaker-Nginx volumes: *http ports: - '80:80' - '443:443' networks: - sysmaker-lan networks: sysmaker-lan: ``` #### for [GitLab CI](https://github.com/Sysmaker-Org/Docker/blob/master/docker-compose.gitlab-ci.yml) to build images ```yaml= # For GitLab to build production images during CI process (rarely change) version: '3.7' services: sysmaker-app: build: context: . target: sysmaker-app image: sysmaker/sysmaker-app:${IMAGE_TAG} sysmaker-api: build: context: . target: sysmaker-api image: sysmaker/sysmaker-api:${IMAGE_TAG} sysmaker-single: build: context: . target: sysmaker-single image: sysmaker/sysmaker:${IMAGE_TAG} ``` ### Configs > `master-0012-4045ddb` ~ `now` #### [**`app.conf`**](https://github.com/Sysmaker-Org/Docker/blob/master/misc/nginx-confd/app.conf) ```clike= server { listen 80; gzip on; gzip_static on; gzip_min_length 4k; gzip_vary on; index index.html; root /usr/share/nginx/html; location / { try_files $uri$args $uri$args/ /index.html; } } ``` #### [**`normal.http(s).conf`**](https://github.com/Sysmaker-Org/Docker/blob/master/misc/nginx-confd/normal.https.conf) * **`https`**: *Uncomment`##`*; **`http`**: *Keep or Remove Lines* ```clike= # Restore original ip from Cloudflare proxy include conf.d/ssl/restore-ip.cloudflare; # Deny requests that are not via our domains server { listen 80 default_server; listen [::]:80 default_server; ## listen 443 default_server; ## listen [::]:443 default_server; server_name _; ## ssl_certificate conf.d/ssl/sysmaker.crt; ## ssl_certificate_key conf.d/ssl/sysmaker.key; return 412; } ### Redirect to HTTPS ##server { ## listen 80; ## server_name *.sysmaker.org localhost; ## return 301 https://$host$request_uri; # redirect http:80 to https ##} server { ## listen 443 ssl; listen 80; server_name *.sysmaker.org localhost; ## ssl_certificate conf.d/ssl/sysmaker.crt; ## ssl_certificate_key conf.d/ssl/sysmaker.key; ## error_page 497 https://$host$request_uri; # redirect http:443 to https location ~ ^/api/v\d+/?.*$ { proxy_pass http://Sysmaker-API; } location / { proxy_pass http://Sysmaker-APP; } } ``` #### [**`single.http(s).conf`**](https://github.com/Sysmaker-Org/Docker/blob/master/misc/nginx-confd/single.https.conf) ```clike= # Restore original ip from Cloudflare proxy include conf.d/ssl/restore-ip.cloudflare; # Deny requests that are not via our domains server { listen 80 default_server; listen [::]:80 default_server; ## listen 443 default_server; ## listen [::]:443 default_server; server_name _; ## ssl_certificate conf.d/ssl/sysmaker.crt; ## ssl_certificate_key conf.d/ssl/sysmaker.key; return 412; } ### Redirect to HTTPS ##server { ## listen 80; ## server_name *.sysmaker.org localhost; ## return 301 https://$host$request_uri; # redirect http:80 to https ##} server { ## listen 443 ssl; listen 80; server_name *.sysmaker.org localhost; ## ssl_certificate conf.d/ssl/sysmaker.crt; ## ssl_certificate_key conf.d/ssl/sysmaker.key; ## error_page 497 https://$host$request_uri; # redirect http:443 to https access_log /dev/stdout; error_log /dev/stderr warn; gzip on; gzip_static on; gzip_min_length 4k; gzip_vary on; index index.html; root /usr/share/nginx/html; location ~ ^/api/v\d+/?.*$ { proxy_set_header Host $host; proxy_pass http://localhost:3000; proxy_redirect off; } location / { try_files $uri$args $uri$args/ /index.html; } } ``` #### [**`restore-ip.cloudflare`**](https://github.com/Sysmaker-Org/Docker/blob/master/misc/ssl/restore-ip.cloudflare) * Required only if you're using Cloudflare proxy ```bash= # Get IP list here: https://www.cloudflare.com/ips/ set_real_ip_from 173.245.48.0/20; set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 108.162.192.0/18; set_real_ip_from 190.93.240.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; set_real_ip_from 162.158.0.0/15; set_real_ip_from 104.16.0.0/12; set_real_ip_from 172.64.0.0/13; set_real_ip_from 131.0.72.0/22; set_real_ip_from 2400:cb00::/32; set_real_ip_from 2606:4700::/32; set_real_ip_from 2803:f800::/32; set_real_ip_from 2405:b500::/32; set_real_ip_from 2405:8100::/32; set_real_ip_from 2a06:98c0::/29; set_real_ip_from 2c0f:f248::/32; # restore original IP real_ip_header CF-Connecting-IP; ```