diff --git a/public/documents/chapter-4-superadmin-build-and-deploy.md b/public/documents/chapter-4-superadmin-build-and-deploy.md index 82f62262..e1dd2335 100644 --- a/public/documents/chapter-4-superadmin-build-and-deploy.md +++ b/public/documents/chapter-4-superadmin-build-and-deploy.md @@ -1,925 +1,1054 @@ -# Build and Deploy Document +# Deploy Document +เอกสารสำหรับการติดตั้งระบบของ BMA HRMS โปรแกรมในยุคปัจจุบันจะทำงานบนเทคโนโลยีคอนเทนเนอร์ เพื่อยืดหยุ่นในการทำงาน ตั้งแต่การพัฒนา ทดสอบและ ใช้งานจริง (Production) จำเป็นต้องเข้าใจการทำงาน Docker เสียก่อน เมื่อเข้าใจหลักการทำงานแล้ว ในอนาคตมีบริการเพิ่มเติมเข้ามาก็จะใช้รูปแบบเดียวกันในการตั้งค่า -- เอกสารนี้เป็นเอกสารสำหรับให้ Developer ดูขั้นตอนการ Deploy ในส่วนของ Test Server และ Production Server สำหรับระบบ BMA eHR +## ติดตั้ง Docker +Docker คอนเทนเนอร์สามารถเรียนรู้ ตั้งค่า ดูแล รักษาได้ง่ายและรวดเร็ว รองรับการขยายตัว สามารถเพิ่มคลัสเตอร์ได้ง่าย และสามารถปรับเปลี่ยนเป็น Kubernates ได้ในอนาคต +สำหรับเอกสารนี้จะเป็นการติดตั้ง Docker บน debian 12 +การติดตั้งโดยละเอียดดูได้จาก [คู่มือในเวปของ Docker](https://docs.docker.com/engine/install/debian/) วิธีการติดตั้งแบบย่อผ่าน +[convenience script](https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script) ทำตามวิธีการนี้ -## TEST Environment +``` +sudo apt install curl +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +sudo usermod -aG docker user_name +sudo usermod -aG sudo user_name +``` +แทน user_name ด้วยยูสเซอร์ที่ใช้ดูแลระบบ ในตัวอย่างให้สิทธิ์ sudo ด้วยเพื่อจะได้มีสิทธิ์ในจัดการไฟล์ที่เกิดจาก docker -1. Environment Diagram +## คำสั่ง Docker พื้นฐาน -![รูปภาพที่ 1 - 1 ](images/buildanddeploy/build1-1.png#center) +คำสั่งพื้นฐานของ docker ที่ใช้ +```sh +docker ps # ดูรายการคอนเทนเนอร์ที่รันอยู่ในระบบ +docker images # ดูรายการอิมเมจที่มีในระบบ +docker pull [image_name:tag] # ดึงอิมเมจมาในระบบ +docker network ls # แสดงรายการเน็ตเวิร์กของ docker +docker network crate [network_name] # สร้างเน็ตเวิร์กของ docker +``` +docker compose จะรันคอนเทนเนอร์ของ docker หลายๆตัวพร้อมกันได้ โดยดูการตั้งค่าจากไฟล์ compose.yaml หรือ docker-compose.yaml +ที่อยู่ในโฟลเดอร์ที่เรียกคำสั่ง ในการทำงานทั่วไปเพื่อที่จะให้ง่ายต่อการใช้งาน จะใช้ docker compose เป็นหลัก -2. หลักการทำงานของระบบ เมื่อมีการ Request มาจากหน้าเว็บ request ทั้งหมดจะถูกส่งมาที่ Traefik ที่เป็นตัว API Gateway โดยที่ตัว Traefik จะดูจาก Rule ที่เราได้ทำการตั้งค่าเอาไว้ที่ docker-compose.yml ว่าเมื่อมีการ Request เข้ามาที่ Url Path ไหนจะทำการ Point ไปที่ Docker Container ตัวใด โดยที่ก่อนใช้งานระบบ จะต้องทำการ Authentication โดยผ่าน Keycloak ซึ่งเมื่อผ่านแล้วจึงจะสามารถใช้งานระบบได้ และเมื่อมีการเรียกใช้งาน API นั้น ตัว API จะทำการ Validate Access Token ที่แนบมากับ Request ทุกครั้งว่า valid หรือไม่ หลังจากนั้น API จะทำการ Query Database ตาม Logic ของ Application แล้วหลังจากนั้น จึงส่งผลลัพธ์กลับไปให้ FrontEnd แสดงผล - -3. เครื่องที่ใช้สำหรับการทดสอบระบบจะติดตั้งอยู่ที่เครื่อง **192.168.1.9** โดยหากเป็นการติดตั้ง Service ที่พัฒนาขึ้นมาใหม่โดยที่ยังไม่เคยทำการติดตั้งมาก่อน จะต้องทำการสร้าง folder สำหรับติดตั้งที่ Server ก่อน ซึ่งการจะเข้าสู่ Server จะต้องทำการ Secure Shell เพื่อเข้าไปยังเครื่อง server โดยใช้คำสั่ง - -```bash - ssh frappet@frappet.com +คำสั่ง docker compose พื้นฐาน (ต้องมีไฟล์ compose ในโฟลเดอร์ที่เรียกคำสั่ง) +```sh +docker compose ps +docker compose up -d +docker compose up -d [service_name] ``` -- หลังจากนั้นให้ใส่รหัสผ่าน ==“FPTadmin2357”== - -4. เมื่อเข้าสู่ server ให้ Chage directory ไปที่ folder /home/docker โดยใช้คำสั่ง - -```bash -cd docker +โฟลเดอร์ที่ใช้เริ่มต้นสร้างโปรแกรม บริการต่างๆในหัวข้อต่อๆไปจะสร้างภายใต้ ~/docker/hrms และใช้เน็ตเวิร์กชื่อ hrms ในการสื่อสารระหว่างกัน ``` - -5. หากต้องการจะดูว่าใน folder นี้มี sub folder อะไรบ้างใช้คำสั่ง - -```bash -ls -la +docker network create hrms +mkdir -p ~/docker/hrms +cd ~/docker/hrms ``` - -- หรือ - -```bash -ls +ทดสอบการทำงานของ docker ให้สร้างโฟลเดอร์ simple-web มีไฟล์ compose.yaml สร้างโฟลเดอร์ html แล้วสร้างไฟล์ html/index.html ในโฟลเดอร์นั้นพร้อมเนื้อหาเรียกคำสั่ง docker compose up -d +เป็นตัวอย่างแบบง่ายเพื่อใช้งาน nginx ไฟล์เวปเก็บในโฟลเดอร์ เปิดพอร์ต 9082 บนเครื่องโฮส ถ้าไม่สั่งหยุดการทำงานจะเริ่มเองถ้าโฮสเปิดขึ้นมาใหม่ ทำงานในเน็ตเวิร์ก hrms +```sh +mkdir -p simple-web/html +cd simple-web +nano compose.yaml +nano html/index.html ``` - -6. หลังจากนั้นสร้าง folder ของ service เช่นหากต้องการสร้าง service ของระบบงาน report ให้ทำการสร้าง folder โดยใช้คำสั่งดังนี้ - -```bash -mkdir bma-ehr-{service name} -``` - -- โดยเปลี่ยน service name เป็นชื่อ service ของตัวเอง เพื่อให้สามารถจำแนกได้ว่า folder นี้เป็น service อะไรของระบบ bma-ehr - -7. ทำการสร้างไฟล์ docker-compose.yml ตามโค้ดตัวอย่าง - +ไฟล์ compose.yaml ```yaml -version: "3.4" - services: - bma-ehr-report-v2: - image: docker.frappet.com/ehr/bma-ehr-report-v2-service:latest - # image: docker.frappet.com/ehr/bma-ehr-report:test-v2 - restart: unless-stopped - ports: - - "6029:80" + web: + image: nginx volumes: - - ./wwwroot:/app/wwwroot - - ./appsettings.json:/app/appsettings.json - - ./appsettings.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-api-report-v2.rule=Host(`bma-ehr.frappet.synology.me`) && PathPrefix(`/api/v2/report`)" + - ./html:/usr/share/nginx/html:ro + ports: + - "9082:80" + restart: unless-stopped networks: - - bma-ehr + hrms: networks: - bma-ehr: + hrms: external: true ``` -8. โดยทำการเปลี่ยนชื่อ Service เป็นชื่อของ docker image service ที่เราจะต้องทำการ push ขึ้น docker registry ของบริษัท -9. เปลี่ยน Port ของ Host **โดย ห้ามซ้ำกับของ Service อื่นๆ** -10. เปลี่ยน Label ในส่วนของชื่อ rule ของ traefik โดยห้ามซ้ำกัน เพราะจะทำให้ Traefik สับสนได้ หลังจากนั้นแก้ URL และ PathPrefix ให้ตรงกับ Path ของตัว API ของเรา -11. สร้าง folder wwwroot เพื่อว่าจะมีการใช้งาน static file -12. สร้าง file appsettings.json เพื่อทำการตั้งค่า config ต่างๆของตัว api ที่จะให้ test env นั้น ต่อฐานข้อมูลไปที่ server ไหน ตามตัวอย่าง **ค่า config ต่างๆอาจจะเปลี่ยนไปตามแต่ละ Service ดังนั้นให้ดูจาก Code ที่ตัวเองเขียนว่ามีการใช้ค่า Config อะไรบ้าง** - -```json -{ - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Information", - "System": "Warning" - } - } - }, - "ElasticConfiguration": { - "Uri": "http://localhost:9200" - }, - "AllowedHosts": "*", - "ConnectionStrings": { - "MongoConnection": "mongodb://admin:adminVM123@bma-mongodb-test1:27017", - "DefaultConnection": "server=bma-mysql-test1;user=root;password=adminVM123;database=bma_ehr;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" - }, - "Jwt": { - "Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI", - "Issuer": "https://id.frappet.synology.me/realms/bma-ehr" - }, - "EPPlus": { - "ExcelPackage": { - "LicenseContext": "NonCommercial" - } - }, - "MinIO": { - "Endpoint": "https://s3cluster.frappet.com/", - "AccessKey": "frappet", - "SecretKey": "FPTadmin2357", - "BucketName": "bma-ehr-fpt" - }, - "Node": { - "API": "https://bma-ehr.frappet.com/api/v1/probation" - }, - "Mail": { - "Server": "smtp.gmail.com", - "User": "suphonchai.ph@gmail.com", - "Password": "nnjazjcnwhepkxdm", - "MailFrom": "suphonchai.ph@gmail.com", - "Port": "587" - }, - "Protocol": "HTTPS", - "API": "https://bma-ehr.frappet.com/api/v1" -} +## Services +การออกแบบใช้สถาปัตยกรรม Microservice จะประกอบจากหลาย Service เพื่อความเป็นระเบียบจะแบ่งไว้สามโฟลเดอร์ apisix(API Gateway), bmahrms-service(3rd Party service), bmahrms(HRMS services) +```sh +mkdir -P apisix +mkdir -p bmahrms-service/{edm_config,elasticsearch_config,init_mysql,keycloak_config,report-server-templates} +ืืmkdir -p bmahrms-service/report-server-templates/{docx,xlsx} +mkdir -p bmahrms ``` -13. หลังจากนั้นให้ทำการสร้าง Dockerfile ไว้ที่ Folder ของ Sourcecode ของ Service ที่เราทำการพัฒนาตามตัวอย่างนี้ โดยแก้ไขค่าให้สอดคล้องกันกับตัวระบบที่เราพัฒนา - -```json -FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base -WORKDIR /app -EXPOSE 80 -EXPOSE 443 - -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build -WORKDIR /src - -COPY ["BMA.EHR.Domain/BMA.EHR.Domain.csproj", "BMA.EHR.Domain/"] -COPY ["BMA.EHR.Application/BMA.EHR.Application.csproj", "BMA.EHR.Application/"] -COPY ["BMA.EHR.Infrastructure/BMA.EHR.Infrastructure.csproj", "BMA.EHR.Infrastructure/"] -COPY ["BMA.EHR.Report.Service/BMA.EHR.Report.Service.csproj", "BMA.EHR.Report.Service/"] - -COPY ./BMA.EHR.Report.Service/Components ./BMA.EHR.Report.Service/Components -COPY ./BMA.EHR.Report.Service/nuget.config ./BMA.EHR.Report.Service/ - -RUN dotnet restore "BMA.EHR.Report.Service/BMA.EHR.Report.Service.csproj" -COPY . . -WORKDIR "/src/BMA.EHR.Report.Service" -RUN dotnet build "BMA.EHR.Report.Service.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "BMA.EHR.Report.Service.csproj" -c Release -o /app/publish /p:UseAppHost=false - -FROM base AS final - -RUN apt-get update && apt-get -y install fontconfig && apt-get install -y --allow-unauthenticated libgdiplus libc6-dev libx11-dev && rm -rf /var/lib/apt/lists/* -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunIT.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunITBold.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunITItalic.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunITBoldItalic.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunNew.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunNewBold.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunNewItalic.ttf /usr/share/fonts/truetype/ -COPY ./BMA.EHR.Report.Service/Fonts/THSarabunNewBoldItalic.ttf /usr/share/fonts/truetype/ -RUN fc-cache -f -v - -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "BMA.EHR.Report.Service.dll"] - +### APISIX +ทำหน้าที่จัดการ https, limit, security, load balance,reverse proxy, และ route ใน Microservice ก่อนใช้งานให้ตั้งค่าโดเมนกับ Public IP ให้เรียบร้อยแล้ว Forward Port 80/443 มาที่เครื่องนี้ +การตั้งค่า route จะทำผ่าน curl(Web API) +```sh +mkdir -p apisix/apisix_conf/ +nano apisix/apisix_conf/config.yaml # configuration +nano apisix/compose.yaml # compose file +docker compose up -d ``` - -14. โดยที่ Dockerfile นี้จะเป็นไฟล์สำคัญที่เราจะใช้ในการ build docker image -15. ทำการสร้างไฟล์ GitHub Action Script โดยดูตัวอย่างได้ จาก Folder ใน Sourcecode - -![รูปภาพที่ 1 - 2 ](images/buildanddeploy/build1-2.png#center) - -16. โดยทำการสร้างไฟล์ release\_{service name}.yaml เพื่อทำการ Build and Deploy ของ Service ที่พัฒนาเพิ่ม ตามตัวอย่าง โดยทำการแก้ไขค่า folder และไฟล์ต่างๆให้ถูกต้องกับ Service ที่กำลังพัฒนา - +apisix/apisix_conf/config.yaml เป็นไฟล์คอนฟิกของ APISIX แก้ค่า put_admin_api_key_here, allow_admin ให้เหมาะสม ```yaml -name: release-dev -run-name: release-dev ${{ github.actor }} -on: - # push: - # tags: - # - 'v[0-9]+.[0-9]+.[0-9]+' - # tags-ignore: - # - '2.*' - # Allow run workflow manually from Action tab - workflow_dispatch: -env: - REGISTRY: docker.frappet.com - IMAGE_NAME: ehr/bma-ehr-report-v2-service - DEPLOY_HOST: frappet.com - COMPOSE_PATH: /home/frappet/docker/bma-ehr-report-v2 - TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0 - -jobs: - # act workflow_dispatch -W .github/workflows/release_report.yaml --input IMAGE_VER=test-v6.1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd - release-dev: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - # skip Set up QEMU because it fail on act and container - - name: Gen Version - id: gen_ver - run: | - if [[ $GITHUB_REF == 'refs/tags/'* ]]; then - IMAGE_VER='${GITHUB_REF/refs\/tags\//}' - else - IMAGE_VER=${{ github.event.inputs.IMAGE_VER }} - fi - if [[ $IMAGE_VER == '' ]]; then - IMAGE_VER='test-vBeta' - fi - echo '::set-output name=image_ver::'$IMAGE_VER - - name: Test Version - run: | - echo $GITHUB_REF - echo ${{ steps.gen_ver.outputs.image_ver }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login in to registry - uses: docker/login-action@v2 - with: - registry: ${{env.REGISTRY}} - username: ${{secrets.DOCKER_USER}} - password: ${{secrets.DOCKER_PASS}} - - name: Build and load local docker image - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64 - file: BMA.EHR.Report.Service/Dockerfile - push: true - tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest - - - name: Reload docker compose - uses: appleboy/ssh-action@v0.1.8 - with: - host: ${{env.DEPLOY_HOST}} - username: frappet - password: ${{ secrets.SSH_PASSWORD }} - port: 22 - script: | - cd "${{env.COMPOSE_PATH}}" - docker-compose pull - docker-compose up -d - echo "${{ steps.gen_ver.outputs.image_ver }}"> success - - uses: snow-actions/line-notify@v1.1.0 - if: success() - with: - access_token: ${{ env.TOKEN_LINE }} - message: | - -Success✅✅✅ - Image: ${{env.IMAGE_NAME}} - Version: ${{ github.event.inputs.IMAGE_VER }} - By: ${{secrets.DOCKER_USER}} - - uses: snow-actions/line-notify@v1.1.0 - if: failure() - with: - access_token: ${{ env.TOKEN_LINE }} - message: | - -Failure❌❌❌ - Image: ${{env.IMAGE_NAME}} - Version: ${{ github.event.inputs.IMAGE_VER }} - By: ${{secrets.DOCKER_USER}} +apisix: + node_listen: 9080 # APISIX listening port + enable_ipv6: false + enable_control: true + control: + ip: "0.0.0.0" + port: 9092 +deployment: + admin: + allow_admin: # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow + - 0.0.0.0/0 # We need to restrict ip access rules for security. 0.0.0.0/0 is for test. + admin_key: + - name: "admin" + key: put_admin_api_key_here + role: admin # admin: manage all configuration data + etcd: + host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster. + - "http://etcd:2379" # multiple etcd address + prefix: "/apisix" # apisix configurations prefix + timeout: 30 # 30 seconds +plugin_attr: + prometheus: + export_addr: + ip: "0.0.0.0" + port: 9091 ``` - -17. ทำการ login ไปที่ https://docker.frappet.com โดยใช้คำสั่งดังนี้ **หากไม่มีรหัส สามารถติดต่อหาพี่อุ้ม หรือพี่แจ๊ค เพื่อขอให้สร้าง username สำหรับใช้งาน Docker Registry** - -```bash -docker login docker.frappet.com -``` - -18. การที่จะรัน Github Action ที่สร้างขึ้นมานั้นจะต้องใช้งาน act ซึ่งเป็น cli จะต้องทำการติดตั้งโปรแกรมนี้ก่อนใช้งาน ซึ่งสามารถทำได้หลายวิธี 1 ในวิธีนั้นคือติดตั้งผ่าน scoop ซึ่งการติดตั้งสามารถเข้าไปดูได้ที่ www.scoop.sh ซึ่งหลังจากติดตั้ง scoop แล้วสามารถติดตั้ง act ได้ผ่านคำสั่ง - -```bash -scoop install act -``` - -19. หลังจากที่ติดตั้ง act แล้วจะทำการ run Github Action เพื่อทำการ Build และ Deploy ไปยัง Test Server โดยใช้คำสั่งนี้ - -```bash -act workflow_dispatch -W .github/workflows/{githib action file} --input IMAGE_VER={image version} -s DOCKER_USER={user name} -s DOCKER_PASS={password} -s SSH_PASSWORD={SSH Password} -``` - -20. ซึ่งระบบจะทำการสร้าง Docker Image และ Push ขึ้นไปไว้ที่ Docker Registry และทำการ Deploy ที่ Test Server ให้โดยอัตโนมัติ ซึ่งหากทำการ Build and Deploy สำเร็จ จะแสดงข้อความดังนี้ - -```bash -| ======CMD====== -| cd "/home/frappet/docker/bma-ehr-report-v2" -| docker-compose pull -| docker-compose up -d -| echo "report-1.0.3"> success -| -| ======END====== -Pulling bma-ehr-report-v2 ... done -Recreating bma-ehr-report-v2_bma-ehr-report-v2_1 ... done -| err: -| ============================================== -| ✅ Successfully executed commands to all host. -| ============================================== -[release-dev/release-dev] ✅ Success - Main Reload docker compose -[release-dev/release-dev] ⭐ Run Main snow-actions/line-notify@v1.1.0 -[release-dev/release-dev] 🐳 docker cp src=C:\Users\***\.cache\act/snow-actions-line-notify@v1.1.0/ dst=/var/run/act/actions/snow-actions-line-notify@v1.1.0/ -[release-dev/release-dev] 🐳 docker exec cmd=[node /var/run/act/actions/snow-actions-line-notify@v1.1.0/index.js] user= workdir= -| {"status":200,"message":"ok"} -[release-dev/release-dev] ✅ Success - Main snow-actions/line-notify@v1.1.0 -[release-dev/release-dev] ⭐ Run Post Build and load local docker image -[release-dev/release-dev] 🐳 docker exec cmd=[node /var/run/act/actions/docker-build-push-action@v3/dist/index.js] user= workdir= -[release-dev/release-dev] ❓ ::group::Removing temp folder /tmp/docker-build-push-3HKDLy -[release-dev/release-dev] ❓ ::endgroup:: -[release-dev/release-dev] ✅ Success - Post Build and load local docker image -[release-dev/release-dev] ⭐ Run Post Login in to registry -[release-dev/release-dev] 🐳 docker exec cmd=[node /var/run/act/actions/docker-login-action@v2/dist/index.js] user= workdir= -[release-dev/release-dev] 💬 ::debug::Exec.getExecOutput: docker logout docker.frappet.com -| [command]/usr/bin/docker logout docker.frappet.com -| Removing login credentials for docker.frappet.com -[release-dev/release-dev] ✅ Success - Post Login in to registry -[release-dev/release-dev] ⭐ Run Post Set up Docker Buildx -[release-dev/release-dev] 🐳 docker exec cmd=[node /var/run/act/actions/docker-setup-buildx-action@v2/dist/index.js] user= workdir= -[release-dev/release-dev] ❓ ::group::Removing builder -[release-dev/release-dev] 💬 ::debug::Buildx.isStandalone: false -[release-dev/release-dev] 💬 ::debug::Exec.getExecOutput: docker buildx inspect builder-4a7bfe0e-828f-4d89-aa5a-7afc470cb2bf -[release-dev/release-dev] 💬 ::debug::Builder.exists: true -[release-dev/release-dev] 💬 ::debug::Buildx.isStandalone: false -| [command]/usr/bin/docker buildx rm builder-4a7bfe0e-828f-4d89-aa5a-7afc470cb2bf -| builder-4a7bfe0e-828f-4d89-aa5a-7afc470cb2bf removed -[release-dev/release-dev] ❓ ::endgroup:: -[release-dev/release-dev] ❓ ::group::Cleaning up certificates -[release-dev/release-dev] ❓ ::endgroup:: -[release-dev/release-dev] ✅ Success - Post Set up Docker Buildx -[release-dev/release-dev] 🏁 Job succeeded -``` - -21. หากเป็นการ Build เพื่อ Update Service เดิมสามารถเริ่มต้นได้ที่ ข้อ 19 ได้เลย - -## Production Environment - -1. Environment Diagram - -![รูปภาพที่ 1 - 3 ](images/buildanddeploy/build1-3.png#center) - -2. หลักการทำงานจะคล้ายๆกับ Test Environment เพียงแต่ว่าตัวฐานข้อมูล mySQL จะถูกสร้างขึ้นเป็น container ของตัว Production โดยเฉพาะ - -3. เนื่องจากเราได้ทำขั้นตอนของการ Build Docker Image ไปในระหว่างการทดสอบระบบแล้ว เราจึงไม่ต้องทำขั้นตอนการ Build Image ซ้ำอีกรอบ เนื่องจาก Image ทั้งหมดจะถูก push ขึ้นไปที่ [https://docker.frappet.com](https://docker.frappet.com) แล้วนั่นเอง - -4. ให้ทำการเพิ่ม Service ที่เราต้องการเพิ่มเติมไปที่ docker-compose File โดยอ้างอิงจาก docker-compose file ของ Service ตัวทดสอบ โดยแก้ไข URL, PathPrefix และ Traefik RuleName ให้ไม่ซ้ำกัน โดยดูจากตัวอย่าง File ด้านล่าง - +apisix/compose.yaml > ```yaml -version: "3.4" services: - bma-mysql-test1: + apisix: + image: apache/apisix:${APISIX_IMAGE_TAG:-3.9.0-debian} + restart: always + environment: + - TZ=Asia/Bangkok + volumes: + - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro + depends_on: + - etcd + ports: + - "9180:9180/tcp" + - "80:9080/tcp" + - "9091:9091/tcp" + - "443:9443/tcp" + - "9092:9092/tcp" + networks: + hrms: + apisix: + etcd: + image: bitnami/etcd:3.5.11 + restart: always + volumes: + - etcd_data:/bitnami/etcd + environment: + ETCD_ENABLE_V2: "true" + ALLOW_NONE_AUTHENTICATION: "yes" + ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379" + ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" + TZ: "Asia/Bangkok" + ports: + - "2379:2379/tcp" + networks: + apisix: +networks: + hrms: + external: true + apisix: + driver: bridge + +volumes: + etcd_data: + driver: local +``` +วิธีการติดตั้ง certificate(HTTPS) เนื่องจากของ *bangkok.go.th มี intermediate certificate +ให้นำ root CA รวมกับ intermediate เพื่อให้พร้อมใช้งาน การตั้งค่า APISIX จะทำผ่าน Web API ใช้ curl และ api-key ที่ตั้งไว้ + +```sh +cat star_bangkok.go.th_2024.crt 'GeoTrust TLS RSA CA G1.crt' > star_bangkok.go.th_2024.ca-bundle +# ใส่ใน APISIX +curl http://127.0.0.1:9180/apisix/admin/ssls/1 \ +-H 'X-API-KEY: put_admin_api_key_here' -X PUT -d ' +{ + "cert" : "'"$(cat star_bangkok.go.th_2024.ca-bundle)"'", + "key": "'"$(cat star_bangkok.go.th_2024.key)"'", + "snis": ["*.bangkok.go.th"] +}' +``` +ถ้ามีการเซ็ต route ผ่าน APISIX สามารถทดสอบ ผ่าน curl ได้ด้วยคำสั่งนี้(การเซ็ตค่าจะอยู่ในหัวข้ออื่น) +```sh +curl https://bma-hrms-id.bangkok.go.th -vvv +``` + + +### 3rd Party Service (bmahrms-service) +โปรแกรมที่พัฒนาโดย 3rd Party หรือ Frappet ถูกใช้โดยโปรแกรมของ HRMS จะแยกมาใส่โฟลเดอร์ bmahrms-service +การติดตั้งให้นำ compose.yaml และ คอนฟิกมาใส่โฟลเดอร์ bmahrms-service ให้เรียบร้อยก่อนใช้งาน สร้างโฟลเดอร์แต่ละ servie ทำดังนี้ + +- Keycloak(bmahrms-postgres bmahrms-id) เซิร์ฟเวอร์สำหรับจัดการยูสเซอร์และการ Authentication ในระบบ +- MySQL(bmahrms-mysql) เป็นฐานข้อมูลของระบบ +- MiniO(bmahrms-s3) เป็น Object Storage ใช้สำหรับเก็บไฟล์ประสิทธิ์ภาพสูงสามารถรับโหลดหนัก การเรียกใช้รวมเร็วปลอดภัยกว่าระบบไฟล์ทั่วไป สามารถขยายเพิ่มได้ในอนาคต ถูกใช้ในหลายระบบที่ต้องการเก็บไฟล์ +- Windmill รันโฟลว์การทำงานอัตโนมัติจากสคริปต์ หลักๆใช้เพื่อรันตัวสำรองข้อมูล +- Portainer(bmahrms-portainer) ระบบจัดการ container มี UI ใช้งานง่าย +- RabbitMQ(bmahrms-mq) ระบบจัดคิวในการสือสารใน Microservice ทำให้รับโหลดหนักๆในช่วงเวลาสั้นๆได้ เช่นระบบการลงเวลา EDM +- Frappet Report Server(bmahrms-report-server) ใช้สำหรับสร้างรายงานจากเอกสารต้นแบบที่ออกแบบเองได้ ส่งออกเป็น docx, xlsx, pdf +- Frappet EDM(bmahrms-edm,bmahrms-elasticsearch,bmahrms-kibana,bmahrms-mq) ใช้สำหรับจัดการเอกสารที่ปลอดภัยรองรับโหลดจำนวนมากได้ จะมีระบบย่อยเบื่องหลังหลายตัว + +docker/bmahrms-service/compose.yaml +```yaml +networks: + hrms: + external: true +#clear all volume: docker volume rm $(docker volume ls -q | grep bmahrms-service) +# clear one volume docker volume rm bmahrms-service_mysql_data +volumes: + keycloak_data: + minio_data: {} + rabbitmq_data: + elasticsearch_data: + postgres_data: + mysql_data: + kibana_data: +services: + bmahrms-id: + image: quay.io/keycloak/keycloak:22.0.0 + restart: unless-stopped + env_file: "service.env" + depends_on: + - bmahrms-postgres + volumes: + - /etc/localtime:/etc/localtime:ro + - keycloak_data:/opt/keycloak/data + - ./keycloak_config:/keycloak_config:ro + command: + - start-dev + - --features=token-exchange + - --https-certificate-file=/keycloak_config/keycloak.crt + - --https-certificate-key-file=/keycloak_config/keycloak.pem + - --http-enabled=true + networks: + - hrms + bmahrms-postgres: + image: postgres:15.3 + restart: unless-stopped + env_file: "service.env" + volumes: + - postgres_data:/var/lib/postgresql/data + networks: + - hrms + bmahrms-s3: + image: minio/minio:RELEASE.2024-07-16T23-46-41Z + env_file: "service.env" + # mem_limit: "1g" + restart: unless-stopped + command: server --console-address ":9001"(bmahrms-postgres bmahrms-id) /data + volumes: + - minio_data:/data + networks: + - hrms + bmahrms-mq: + image: rabbitmq:3-management-alpine + env_file: "service.env" + mem_limit: "1g" + restart: unless-stopped + environment: + - TZ=Asia/Bangkok + - RABBITMQ_DEFAULT_USER=admin + - RABBITMQ_DEFAULT_PASS=MQ_PASSWORD + ports: + - 5672:5672 + # - 9122:15672 # UI + volumes: + - rabbitmq_data:/var/lib/rabbitmq/ + networks: + - hrms + bmahrms-mysql: image: mysql:8.0.17 - command: ["--max_connections=5000"] + env_file: "service.env" + command: [ "--max_connections=5000" ] restart: unless-stopped ports: - - "4061:3306" + - "9123:3306" volumes: - - ./mysql-data:/var/lib/mysql + - mysql_data:/var/lib/mysql - ./init_mysql:/docker-entrypoint-initdb.d/:ro - environment: - TZ: Asia/Bangkok - MYSQL_ROOT_PASSWORD: adminVM123 - MYSQL_DATABASE: bma_ehr - MYSQL_USER: frappet - MYSQL_PASSWORD: P@ssw0rd networks: - - bma-ehr - bma-mongodb-test1: - image: mongo:4.2.0 - command: [--auth] + - hrms + bmahrms-report-server: + image: docker.frappet.com/demo/report-server:latest restart: unless-stopped + mem_limit: 1000m + volumes: + - ./report-server-templates:/app/templates + networks: + - hrms + bmahrms-elasticsearch: + image: docker.frappet.com/core/elasticsearch-icu:8.14.3 + env_file: "service.env" + mem_limit: "4g" + volumes: + - elasticsearch_data:/usr/share/elasticsearch/data + - ./elasticsearch_config/config.yaml:/usr/share/elasticsearch/config/elasticsearch.yml + restart: unless-stopped + # disable ulimits for Proxmox LXC + # ulimits: + # memlock: + # soft: -1 + # hard: -1 + networks: + - hrms + bmahrms-kibana: + image: docker.elastic.co/kibana/kibana:8.14.3 + env_file: "service.env" + depends_on: + - bmahrms-elasticsearch + volumes: + - kibana_data:/usr/share/kibana/data ports: - - "4062:27017" - volumes: - - ./mongo-data:/data/db - environment: - TZ: Asia/Bangkok - MONGO_INITDB_ROOT_USERNAME: admin - MONGO_INITDB_ROOT_PASSWORD: adminVM123 + - 2130:5601 + restart: always networks: - - bma-ehr + - hrms + bmahrms-edm: + image: docker.frappet.com/edm/core + restart: unless-stopped + volumes: + - ./edm_config/keycloak.json:/app/static/keycloak.json:ro + environment: + - PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvfonxaaTELBLHYHTUxateIYMdjGP/yKuzTnNmuinplH2e0QbDJ2q7NsQh2X0YndiQ1uJEU5dFWWFi1D8TEnoVmqW7dxoQ1yXdNB1GvUbhgdT2btoRzzbXeluIVM2oNPtTHu5q5yhnEq/3ldWIkJwQjEkoKv50biDUSTxA0c/R3BLTIMIO6ZUe4ael06e34iSxdP3Dyw3IKTEHaqG1d37SMhfaZ25lA8QGjygiq733l2PfBiVgnjqcy+uvyXkWTjthTNSic3eaSXiIEtxyC4kAGrR/3qClZC8JEgf6mOFmoHna/eSStYodCTOj7SVUmujlMyvE8mGI9BslU/n4RLCuQIDAQAB + - REALM_URL=https://bma-hrms-id.bangkok.go.th/realms/EDM + - PREFERRED_AUTH=online + - MANAGEMENT_ROLE=doc-management + - MINIO_HOST=bmahrms-s3.bangkok.go.th + - MINIO_PORT=443 + - MINIO_SSL=true + - MINIO_ACCESS_KEY=dIYTJ2nXmD9cDln7yrwE + - MINIO_SECRET_KEY=pENPrGWpkngbLHnPBBh0dp2BoMQL5KZH60MucN6I + # Bucket notification event needed to be configured + # Can use prepare script to create bucket + - MINIO_BUCKET=edm + - ELASTICSEARCH_PROTOCOL=http + - ELASTICSEARCH_HOST=bmahrms-elasticsearch + - ELASTICSEARCH_PORT=9200 + # Can use prepare script + - ELASTICSEARCH_INDEX=edm-index + - AMQ_URL=amqp://admin:admin123456@bmahrms-mq:5672 + - AMQ_QUEUE=edm + - NODE_TLS_REJECT_UNAUTHORIZED=false + extra_hosts: + - bma-hrms-id.bangkok.go.th:192.168.2.101 + depends_on: + - bmahrms-postgres - bma-ehr-test1: + networks: + - hrms + bmahrms-portainer: + image: portainer/portainer-ce:2.20.3 + volumes: + - portainer_data:/data + - /var/run/docker.sock:/var/run/docker.sock + restart: unless-stopped + networks: + - hrms +``` +รันคำสั่งดังนี้ในตัวอย่างเรียกใช้งาน Keycloak จะใช้ 2 service ตัวอย่างนี้จะเรียกใช้ฐานข้อมูลแล้วค่อยเรียกใช้โปรแกรม keycloak +```sh +docker compose up -d bmahrms-postgres +docker compose up -d bmahrms-id +``` +### BMA HRMS Service +ระบบที่พัฒนาเพื่อ HRMS โดยเฉพาะ จะมี 3 ไฟล์ +- be.env ค่าคอนฟิกของ Backend +- fe.env ค่าตอนฟิกของ Frontend +- compose.yaml คอนฟิกของ Docker + +โปรแกรม Frntend เป็นส่วนของหน้าเวปเพื่อใช้งาน + +- bmahrms เว็บไซต์สำหรับ Officer +- bmahrms-user เว็บไซต์ ระบบบริการเจ้าของข้อมูล +- bmahrms-admin ระบบ Admin +- bmahrms-checkin เว็บไซต์ ระบบลงเวลา +- bmahrms-publish เว็บไซต์ เผยแพร่ผลงาน +- bmahrms-candidate-register เว็บไซต์สำหรับรับสมัครสอบคัดเลือก +- bmahrms-qualifying-exam-cms เว็บไซต์ศูนย์ข้อมูลการสรรหาบุคคลของกรุงเทพมหานคร(CMS) +- bmahrms-manual ระบบคู่มือ +- bmahrms-faq เว็บไซต์ FAQ +- bmahrms-logs-n-backup Backup and Logs + +โปรแกรม Backend ถูกเรียกใช้โดย Frontend อีกที +- bmahrms-report +- bmahrms-recruit +- bmahrms-insignia +- bmahrms-recruit-exam +- bmahrms-org-employee +- bmahrms-placement +- bmahrms-retirement +- bmahrms-report-v2 +- bmahrms-probation +- bmahrms-command +- bmahrms-discipline +- bmahrms-evaluation +- bmahrms-leave +- bmahrms-org +- bmahrms-salary +- bmahrms-development +- bmahrms-kpi + + +docker/bmahrms/fe.env แก้ตัวแปร VITE_CLIENTSECRET_KEYCLOAK KC_SERVICE_ACCOUNT_SECRET +``` +# Frontend Global +TZ=Asia/Bangkok +VITE_COMPETITIVE_EXAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/KO0GpSu4z?orgId=1 +VITE_QUALIFY_DISABLE_EMAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/dQQzpIX4z?orgId=1 +VITE_QUALIFY_EXAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/cj1ZtIX4z?orgId=1 +VITE_S3CLUSTER_PUBLIC_URL=https://bma-hrms-s3.bangkok.go.th/bma-ehr-fpt/organization/strueture/ +VITE_REALM_KEYCLOAK=bma-ehr +VITE_URL_KEYCLOAK=https://bma-hrms-id.bangkok.go.th +VITE_CLIENTID_KEYCLOAK: "gettoken" +VITE_CLIENTSECRET_KEYCLOAK: put_client_secret_keycloak_here +VITE_API_REPORT_URL=https://bma-hrms.bangkok.go.th/api/v1/report-template +# เผยแพร่ผลงาน +VITE_API_PUBLISH_URL=https://bma-hrms-publish.bangkok.go.th + +# Admin +VITE_API_URI_CONFIG=https://bma-hris.bangkok.go.th/api/v1 +KC_URL=https://bma-hrms-id.bangkok.go.th +KC_REALM=bma-ehr +KC_SERVICE_ACCOUNT_CLIENT_ID=bma-ehr-dev +KC_SERVICE_ACCOUNT_SECRET=put_service_account_secret_here +MANAGEMENT_ROLE=storage_management +``` +docker/bmahrms/be.env แก้ค่าของ DB_PASSWORD,AUTH_PUBLIC_KEY, MINIO_KEY, MINIO_SECRET, STORAGE_SECRET,KC_SERVICE_ACCOUNT_SECRET,REDIS_HOST,KEYCLOAK_KEY,AUTH_PUBLIC_KEY, PUBLIC_KEY +``` +# Backend Global +TZ=Asia/Bangkok +ASPNETCORE_ENVIRONMENT=Development +APP_HOST=0.0.0.0 +APP_PORT=80 +HOST=0.0.0.0 +PORT=80 +DB_HOST=bmahrms-mysql +DB_PORT=3306 +DB_USERNAME=root +DB_NAME=bma_ehr_organization_demo +DB_PASSWORD=DB_PASSWORD +AUTH_REALM_URL=https://bmahrms-id.bangkok.go.th/realms/bma-ehr +AUTH_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkOrQxwoFeJE5TPXeSGL8IRDYVEL1OzmBuywNAzsL9vdcDUrjRA+Ocfp1pwLxXbNPacIgVmP1G+Cf3Steyp5ZeYAGL3u/MRHhUZA1tRbJ9sT+i/JzubmJCs9uF2pV9dLyT6kP7ZjKXmFBzHcXTS/GZMRtz8HZjB6ZzegFtV2oIrQq4+zo4BlzIAI6vaZfKn/JrTjJEbti0RQcqWfIldE918SQvZHzi3Upgn+OBopSRCrF7z3a7FEjYI1Vny42f5dBUcAmDDxOKqoJN09ArYchWkiDGvfpVarsclodptAGKwLuIDwDm9T9cnBUcBzWKNkwpQD3LvydOFVJRBqHAOrfEQIDAQAB +AUTH_PREFERRED_MODE=online +API=https://bma-hrms.bangkok.go.th/api/v1/ +SECRET_KEY=put_secret_key_here +MINIO_HOST=https://bmahrms-s3.bangkok.go.th +MINIO_PORT=9000 +MINIO_ACCESS_KEY=MINIO_KEY +MINIO_SECRET_KEY=MINIO_SECRET +MINIO_BUCKET=bma-ehr-fpt +API_URL=https://bmahrms.bangkok.go.th/api/v1 +STORAGE_URL=https://bmahrms-edm.bangkok.go.th/api +STORAGE_REALM_URL=https://edm-id.bangkok.go.th/realms/EDM +STORAGE_SECRET=put_storage_secret_here +KC_URL=https://bmahris-id.bangkok.go.th +KC_REALM=bma-ehr +KC_SERVICE_ACCOUNT_CLIENT_ID=bma-ehr-dev +KC_SERVICE_ACCOUNT_SECRET=put_account_secret_here +MANAGEMENT_ROLE=storage_management +REDIS_HOST=192.168.1.81 +REDIS_PORT=6379 + +KEYCLOAK_URL=https://bma-hrms-id.bangkok.go.th/realms/bma-ehr +KEYCLOAK_KEY=CNnpzJkwbk7jvI5Lb6gP5_Ok0WpDJJ50Mn0aD55Bd5E +KEYCLOAK_REALM=bma-ehr + +PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYg0ZJvH6HgNOzyPp7PCvY3bJwD9WdsNn6gZbuvIfqJQZ8iSH1t0p3fgODO/fqwcj9UFeh1bVFOSjuW+JpnPehROqzt81KNl9zLLNXoN4LimReQHaMM3dU7DCbRylgVCouIDvObyjg8G+Cy5lZvFKWym/DPwGVpSdbvDZJ83qxq2dp7GJXS8PhOvA+MB1K009/jW5pBTUwNArLjoFccr+gIYIiOJDg2rYyIF3fDkwyWkuxr6xRt10+BRJytselwy/18kbDuJxVPaapdgTXI6wLzx7HWcDk30n5EvhJEumnIPpRst8gucqNYmB4MH+vsyoxV5WLuO3qmVRzFbtAppRQIDAQAB +REALM_URL=https://bmahrms-id.bangkok.go.th/realms/bma-ehr +PREFERRED_MODE=online +PREFERRED_AUTH=online + +ELASTICSEARCH_PROTOCOL=http +ELASTICSEARCH_HOST=bmahrms-elasticsearch +ELASTICSEARCH_PORT=9200 +ELASTICSEARCH_INDEX=bma-ehr-log-index +``` +docker/bmahrms/compose.yaml +```yaml +networks: + hrms: + external: true +services: + # Start Frontend Section + # เว็บไซต์สำหรับ Officer + bmahrms: + container_name: bmahrms image: docker.frappet.com/ehr/bma-ehr-app:latest - restart: unless-stopped - labels: - - traefik.enable=true - - traefik.http.routers.bma-ehr-test1.rule=Host(`bma-ehr.frappet.com`) - - "traefik.http.routers.bma-ehr-test1.entrypoints=unsecure" - environment: - TZ: Asia/Bangkok - VITE_COMPETITIVE_EXAM_PANEL: "https://bma-dashboard.frappet.synology.me/goto/D222MQQVk?orgId=1" - VITE_QUALIFY_DISABLE_EMAM_PANEL: "https://bma-dashboard.frappet.synology.me/goto/i0RoGQw4k?orgId=1" - VITE_QUALIFY_EXAM_PANEL: "https://bma-dashboard.frappet.synology.me/goto/RQXtGQQ4z?orgId=1" - VITE_S3CLUSTER_PUBLIC_URL: "https://s3cluster.frappet.com/bma-ehr-fpt/organization/strueture/" + restart: always + env_file: "fe.env" + ports: + - "6021:80" networks: - - bma-ehr - - bma-ehr-metadata-test1: - image: docker.frappet.com/ehr/bma-ehr-metadata-service:latest - restart: unless-stopped - # ports: - # - "4065:80" - volumes: - - ./appsettings-metadata.json:/app/appsettings.json - - ./appsettings-metadata.json:/app/appsettings.Development.json - labels: - - "traefik.enable=true" - - "traefik.http.routers.bma-ehr-metadata-test1.rule=Host(`bma-ehr.frappet.com`) && PathPrefix(`/api/v1`)" - - "traefik.http.routers.bma-ehr-metadata-test1.entrypoints=unsecure" + - hrms + # เว็บไซต์สำหรับรับสมัครสอบคัดเลือก + bmahrms-candidate-register: + image: docker.frappet.com/ehr/bma-ehr-recruit-exam:latest + container_name: bmahrms-candidate-register + env_file: "fe.env" + restart: always environment: - TZ: Asia/Bangkok - # ASPNETCORE_ENVIRONMENT: Development + VITE_API_URI_CONFIG: "https://bmahrms.bangkok.go.th/api" + VITE_CLIENTID_KEYCLOAK: "bma-ehr-exam-vue3" + ports: + - "6022:80" networks: - - bma-ehr + - hrms + # เว็บไซต์ศูนย์ข้อมูลการสรรหาบุคคลของกรุงเทพมหานคร(CMS) + # CMS ระบบสมัครสอบ + bmahrms-qualifying-exam-cms: + image: docker.frappet.com/demo/qualifying-exam-cms:latest + container_name: bmahrms-qualifying-exam-cms + restart: always + env_file: "fe.env" + ports: + - "6023:80" + environment: + API_CMS_URL: "https://bmahrms.bangkok.go.th/api/v1/cms" + API_QUALIFYING_URL: "https://bmahrms.bangkok.go.th/api/v1/cms" + API_COMPETITIVE_URL: "https://bmahrms.bangkok.go.th/api/v1/recruit" + PUBLIC_URL_REGISTER_QUALIFY_EXAM: "https://bmahrms-apply.bangkok.go.th" + networks: + - hrms + # ระบบคู่มือ + bmahrms-manual: + image: docker.frappet.com/ehr/bma-ehr-manual:latest + container_name: bmahrms-manual + restart: always + env_file: "fe.env" + ports: + - "6024:80" + networks: + - hrms + # เว็บไซต์ ระบบบริการเจ้าของข้อมูล + bmahrms-user: + image: docker.frappet.com/ehr/bma-ehr-user:latest + container_name: bmahrms-user + restart: always + env_file: "fe.env" + ports: + - "6025:8087" + networks: + - hrms + # เว็บไซต์ ระบบลงเวลา + bmahrms-checkin: + image: docker.frappet.com/ehr/bma-ehr-checkin:latest + container_name: bmahrms-checkin + restart: always + env_file: "fe.env" + ports: + - "6026:80" + networks: + - hrms + # เว็บไซต์ เผยแพร่ผลงาน + bmahrms-publish: + image: docker.frappet.com/ehr/bma-ehr-publish:latest + container_name: bmahrms-publish + restart: always + env_file: "fe.env" + ports: + - "6027:80" + environment: + VITE_API_URI_CONFIG: "https://bmahrms.bangkok.go.th/api/v1" + VITE_API_PUBLISH_URL: "https://bmahrms.bangkok.go.th/api/v1/evaluation" + networks: + - hrms + # เว็บไซต์ FAQ + bmahrms-faq: + image: docker.frappet.com/ehr/bma-ehr-faq:latest + container_name: bmahrms-faq + restart: always + env_file: "fe.env" + ports: + - "6028:80" + networks: + - hrms + # ระบบ Admin + bmahrms-admin: + container_name: bmahrms-admin + image: docker.frappet.com/ehr/bma-ehr-admin:latest + env_file: "fe.env" + restart: always + ports: + - "6029:8086" + environment: + VITE_CLIENTID_KEYCLOAK: "HRIS_ADMIN" + VITE_API_URI_CONFIG: "https://bma-hrms.bangkok.go.th/api/v1" + KC_REALM: "bma-ehr" + KC_SERVICE_ACCOUNT_CLIENT_ID: "bma-ehr-dev" + KC_SERVICE_ACCOUNT_SECRET: "f2mp7Xj4nz6gbgITve9J7AHXZI8dRhOd" + MANAGEMENT_ROLE: "storage_management" + networks: + - hrms + # Backup and Logs + bmahrms-logs-n-backup: + container_name: bmahrms-logs-n-backup + image: docker.frappet.com/ehr/bma-ehr-log-backup:latest + restart: always + env_file: "fe.env" + ports: + - 6030:3000 + environment: + - KC_REALM_URL=https://bma-hrms-id.bangkok.go.th/realms/bma-ehr + - ELASTICSEARCH_PROTOCOL=http + - ELASTICSEARCH_HOST=192.168.1.40 + - ELASTICSEARCH_PORT=9200 + - ELASTICSEARCH_INDEX=bma-ehr-log-dotcom-index + - APP_HOST=0.0.0.0 + - APP_PORT=3000 + - WINDMILL_URL=http://host.docker.internal:20001 + - WINDMILL_WORKSPACE=bma-ehr + - WINDMILL_BACKUP_FLOW_PATH=f/flow/full_backup_s3_mysql + - WINDMILL_RESTORE_FLOW_PATH=f/flow/full_restore_s3_mysql + - WINDMILL_BACKUP_DELETE_SCRIPT_PATH=f/flow/delete_backup_s3_mysql + - WINDMILL_BACKUP_LIST_SCRIPT_PATH=f/flow/list_backup_s3_mysql + - WINDMILL_API_KEY=I843JmwwcRKouMnE1DkTBRjiKl6yzkXM + - DB_HOST="bma-mysql-ehr" + - DB_PORT=3306 + - DB_USERNAME=root + - DB_PASSWORD=adminVM123 + - DB_LIST=bma_ehr,bma_ehr_development,bma_ehr_discipline,bma_ehr_evaluation,bma_ehr_exam,bma_ehr_history,bma_ehr_kpi,bma_ehr_leave,bma_ehr_organization,bma_ehr_probation,bma_ehr_salary,bma_ehr_support,bma_recruit + - MAIN_MINIO_USE_SSL=true + - MAIN_MINIO_HOST=bma-hrms-s3.bangkok.go.th + - MAIN_MINIO_PORT=443 + - MAIN_MINIO_ACCESS_KEY=put_minio_access_key_here + - MAIN_MINIO_SECRET_KEY=put_minio_secret_key_here + - MAIN_MINIO_BUCKET=bma-ehr-fpt + - BACKUP_MINIO_USE_SSL=true + - BACKUP_MINIO_HOST=bma-hrms-s3.bangkok.go.th + - BACKUP_MINIO_PORT=443 + - BACKUP_MINIO_ACCESS_KEY=put_backup_minio_access_key_here + - BACKUP_MINIO_SECRET_KEY=put_backup_minio_secret_key_here + - BACKUP_MINIO_BUCKET=bma-ehr-fpt-backup-dotcom + extra_hosts: + - host.docker.internal:host-gateway + networks: + - hrms + # End Frontend Section - bma-ehr-profile-test1: - image: docker.frappet.com/ehr/bma-ehr-profile-service:latest + # Start Backend Section + bmahrms-report: + image: docker.frappet.com/ehr/bma-ehr-report-service:latest + container_name: bmahrms-report + env_file: "be.env" restart: always # ports: - # - "4066:80" - volumes: - - ./wwwroot:/app/wwwroot - - ./appsettings-profile.json:/app/appsettings.json - - ./appsettings-profile.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - # ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-profile-test1.rule=Host(`bma-ehr.frappet.com`) && PathPrefix(`/api/v1/profile`)" - networks: - - bma-ehr - - bma-ehr-organization-test1: - image: docker.frappet.com/ehr/bma-ehr-organization-service:latest - restart: - unless-stopped - # ports: - # - "4067:80" - volumes: - - ./appsettings-organization.json:/app/appsettings.json - - ./appsettings-organization.json:/app/appsettings.Development.json - labels: - - "traefik.enable=true" - - "traefik.http.routers.bma-ehr-organization-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/Organization`)||PathPrefix(`/api/v1/PositionMaster`)||PathPrefix(`/api/v1/report2`))" - - "traefik.http.routers.bma-ehr-organization-test1.entrypoints=unsecure" - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - networks: - - bma-ehr - bma-ehr-recruit-test1: - image: docker.frappet.com/ehr/bma-ehr-recruit-service:latest - restart: unless-stopped - # ports: - # - "4068:80" - volumes: - - ./wwwroot:/app/wwwroot - - ./appsettings-recruit.json:/app/appsettings.json - - ./appsettings-recruit.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-api-recruit-test1.rule=Host(`bma-ehr.frappet.com`) && PathPrefix(`/api/v1/recruit`)" - networks: - - bma-ehr - bma-ehr-report-test1: - image: docker.frappet.com/ehr/bma-ehr-report-service:latest - restart: unless-stopped - # ports: - # - "5026:80" + # - "7020:80" volumes: - ./wwwroot:/app/wwwroot - ./appsettings-report.json:/app/appsettings.json - ./appsettings-report.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - # ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-api-report-test1.rule=Host(`bma-ehr.frappet.com`) && PathPrefix(`/api/v1/report`)" networks: - - bma-ehr + - hrms - # เว็บไซต์สำหรับรับสมัครสอบคัดเลือก : bma-apply.frappet.com - bma-ehr-candidate-register-test1: - image: docker.frappet.com/ehr/bma-ehr-recruit-exam:latest - restart: unless-stopped - environment: - TZ: Asia/Bangkok - VITE_API_URI_CONFIG: "https://bma-ehr.frappet.com/api/v1" - labels: - - traefik.enable=true - - traefik.http.routers.bma-ehr-candidate-register-test1.rule=Host(`bma-apply.frappet.com`) + bmahrms-recruit: + container_name: bmahrms-recruit + image: docker.frappet.com/ehr/bma-ehr-recruit-service:latest + restart: always + env_file: "be.env" + # ports: + # - "7021:80" + volumes: + - ./wwwroot:/app/wwwroot + - ./appsettings-recruit.json:/app/appsettings.json + - ./appsettings-recruit.json:/app/appsettings.Development.json networks: - - bma-ehr - bma-ehr-recruit-exam-test1: + - hrms + + bmahrms-insignia: + image: docker.frappet.com/ehr/bma-ehr-insignia-service:latest + container_name: bmahrms-insignia + restart: always + env_file: "be.env" + # ports: + # - "7022:80" + volumes: + - ./wwwroot:/app/wwwroot + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json + networks: + - hrms + + bmahrms-recruit-exam: image: docker.frappet.com/ehr/bma-ehr-recruit-exam-service:latest - restart: unless-stopped - ports: - - "4069:80" + container_name: bmahrms-recruit-exam + restart: always + env_file: "be.env" + # ports: + # - "7023:80" volumes: - ./wwwroot:/app/wwwroot - ./appsettings-recruit-exam.json:/app/appsettings.json - ./appsettings-recruit-exam.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-candidate-exam-test1.rule=Host(`bma-ehr.frappet.com`) && ( PathPrefix(`/api/v1/cms`) || PathPrefix(`/api/v1/candidate`) )" networks: - - bma-ehr - # เว็บไซต์ศูนย์ข้อมูลการสรรหาบุคคลของกรุงเทพมหานคร(CMS): bma-recruit.frappet.com - bma-ehr-qualifying-exam-cms-test1: - image: docker.frappet.com/demo/qualifying-exam-cms:latest - restart: unless-stopped - # ports: - # - "4028:80" - environment: - TZ: Asia/Bangkok - API_CMS_URL: "https://bma-ehr.frappet.com/api/v1/cms" - API_QUALIFYING_URL: "https://bma-ehr.frappet.com/api/v1/cms" - API_COMPETITIVE_URL: "https://bma-ehr.frappet.com/api/v1/recruit" - PUBLIC_URL_REGISTER_QUALIFY_EXAM: "https://bma-apply.frappet.com" - labels: - - traefik.enable=true - - traefik.http.routers.bma-ehr-qualifying-exam-cms-test1.rule=Host(`bma-recruit.frappet.com`) - networks: - - bma-ehr + - hrms - bma-ehr-insignia-test1: - image: docker.frappet.com/ehr/bma-ehr-insignia-service:latest - restart: unless-stopped - # ports: - # - "4031:80" - volumes: - - ./wwwroot:/app/wwwroot - - ./appsettings-insignia.json:/app/appsettings.json - - ./appsettings-insignia.json:/app/appsettings.Development.json - - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-insignia-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/insignia`))" - networks: - - bma-ehr - - bma-ehr-org-employee-test1: + bmahrms-org-employee: image: docker.frappet.com/ehr/bma-ehr-org-employee-service:latest - restart: unless-stopped + container_name: bmahrms-org-employee + restart: always + env_file: "be.env" # ports: - # - "4026:80" + # - "7024:80" volumes: - ./wwwroot:/app/wwwroot - - ./appsettings-org-employee.json:/app/appsettings.json - - ./appsettings-org-employee.json:/app/appsettings.Development.json - - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-org-employee-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/organization-employee`))" + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json networks: - - bma-ehr + - hrms - bma-ehr-placement-test1: + bmahrms-placement: image: docker.frappet.com/ehr/bma-ehr-placement-service:latest - restart: unless-stopped + container_name: bmahrms-placement + restart: always + env_file: "be.env" # ports: - # - "4032:80" + # - "7025:80" volumes: - ./wwwroot:/app/wwwroot - - ./appsettings-placement.json:/app/appsettings.json - - ./appsettings-placement.json:/app/appsettings.Development.json - - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-placement-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/placement`))" + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json networks: - - bma-ehr + - hrms - bma-ehr-retirement-test1: + bmahrms-retirement: image: docker.frappet.com/ehr/bma-ehr-retirement-service:latest - restart: unless-stopped + container_name: bmahrms-retirement + restart: always + env_file: "be.env" # ports: - # - "4030:80" + # - "7026:80" volumes: - ./wwwroot:/app/wwwroot - - ./appsettings-retirement.json:/app/appsettings.json - - ./appsettings-retirement.json:/app/appsettings.Development.json - - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-retirement-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/retirement`))" + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json networks: - - bma-ehr + - hrms - bma-ehr-report-v2-test1: + bmahrms-report-v2: image: docker.frappet.com/ehr/bma-ehr-report-v2-service:latest - # image: docker.frappet.com/ehr/bma-ehr-report:test-v2 - restart: unless-stopped + container_name: bmahrms-report-v2 + restart: always + env_file: "be.env" # ports: - # - "6029:80" + # - "7027:80" volumes: - ./wwwroot:/app/wwwroot - ./appsettings-report-v2.json:/app/appsettings.json - ./appsettings-report-v2.json:/app/appsettings.Development.json - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-api-report-v2-test1.rule=Host(`bma-ehr.frappet.com`) && PathPrefix(`/api/v2/report`)" networks: - - bma-ehr + - hrms - bma-ehr-probation-test1: - image: docker.frappet.com/ehr/bma-ehr-node-service:version-1.0.1 - restart: unless-stopped + bmahrms-probation: + image: docker.frappet.com/ehr/bma-ehr-node-service:latest + container_name: bmahrms-probation + restart: always + env_file: "be.env" # ports: - # - "4033:8080" - # volumes: - # - ./wwwroot:/app/wwwroot - # - ./appsettings.json:/app/appsettings.json - # - ./appsettings.json:/app/appsettings.Development.json - + # - "7028:80" environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - HOST: "0.0.0.0" - PORT: "8080" - DB_HOST: "bma-mysql-test1" - DB_PORT: "3306" - DB_USER: "root" - DB_NAME: "bma_ehr" - DB_PASSWORD: "adminVM123" - API_URL: "https://bma-ehr.frappet.com/api/v1" - KEYCLOAK_URL: "https://id.frappet.synology.me/realms/bma-ehr" - KEYCLOAK_KEY: "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI" - KEYCLOAK_REALM: "bma-ehr" - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-probation-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/probation`))" + DB_NAME: "bma_ehr_probation" networks: - - bma-ehr + - hrms - bma-ehr-command-test1: + bmahrms-command: image: docker.frappet.com/ehr/bma-ehr-command-service:latest - restart: unless-stopped + container_name: bmahrms-command + restart: always + env_file: "be.env" # ports: - # - "6026:80" + # - "7029:80" volumes: - ./wwwroot:/app/wwwroot - - ./appsettings-command.json:/app/appsettings.json - - ./appsettings-command.json:/app/appsettings.Development.json - - environment: - TZ: Asia/Bangkok - ASPNETCORE_ENVIRONMENT: Development - labels: - - traefik.enable=true - - "traefik.http.routers.bma-ehr-command-test1.rule=Host(`bma-ehr.frappet.com`) && (PathPrefix(`/api/v1/order`) || PathPrefix(`/api/v1/message`))" + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json networks: - - bma-ehr + - hrms - bma-ehr-manual-test1: - image: docker.frappet.com/ehr/bma-ehr-manual:latest + bmahrms-discipline: + image: docker.frappet.com/ehr/bma-ehr-discipline-service:latest + container_name: bmahrms-discipline restart: always + # env_file: "be.env" # ports: - # - "6023:80" - environment: - TZ: Asia/Bangkok - labels: - - traefik.enable=true - - traefik.http.routers.bma-ehr-manual-test1.rule=Host(`bma-ehr-manual.frappet.com`) + # - "7030:80" + volumes: + - ./wwwroot:/app/wwwroot + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json networks: - - bma-ehr + - hrms - bma-ehr-user-test1: - image: docker.frappet.com/ehr/bma-ehr-user:latest - restart: unless-stopped + bmahrms-evaluation: + image: docker.frappet.com/ehr/bma-ehr-evaluation-service:latest + container_name: bmahrms-evaluation + restart: always + env_file: "be.env" # ports: - # - "6022:80" + # - "7031:80" environment: - TZ: Asia/Bangkok - VITE_API_URI_CONFIG: "https://bma-ehr.frappet.com/api/v1" - labels: - - traefik.enable=true - - traefik.http.routers.bma-ehr-user-test1.rule=Host(`bma-ehr-user.frappet.com`) - - "traefik.http.routers.bma-ehr-user-test1.entrypoints=unsecure" + DB_NAME: "bma_ehr_evaluation" networks: - - bma-ehr + - hrms -networks: - bma-ehr: - external: true + bmahrms-leave: + image: docker.frappet.com/ehr/bma-ehr-leave-service:latest + container_name: bmahrms-leave + restart: always + env_file: "be.env" + # ports: + # - "7032:80" + volumes: + - ./wwwroot:/app/wwwroot + - ./appsettings-combine.json:/app/appsettings.json + - ./appsettings-combine.json:/app/appsettings.Development.json + networks: + - hrms + + bmahrms-org: + image: docker.frappet.com/ehr/bma-ehr-org-service:latest + container_name: bmahrms-org + restart: always + env_file: "be.env" + # ports: + # - "7033:80" + environment: + DB_NAME: "bma_ehr_organization" + networks: + - hrms + + bmahrms-salary: + image: docker.frappet.com/ehr/bma-ehr-salary-service:latest + container_name: bmahrms-salary + restart: always + env_file: "be.env" + # ports: + # - "7034:80" + environment: + DB_NAME: "bma_ehr_salary" + networks: + - hrms + + bmahrms-development: + image: docker.frappet.com/ehr/bma-ehr-development-service:latest + container_name: bmahrms-development + restart: always + env_file: "be.env" + # ports: + # - "7035:80" + environment: + DB_NAME: "bma_ehr_development" + networks: + - hrms + + bmahrms-kpi: + image: docker.frappet.com/ehr/bma-ehr-kpi-service:latest + container_name: bmahrms-kpi + restart: always + env_file: "be.env" + # ports: + # - "7036:80" + environment: + DB_NAME: "bma_ehr_kpi" + networks: + - hrms + # End Backend Section ``` -5. หลังจากนั้นให้เข้าไปที่ folder ของตัวระบบ Production แล้วรันคำสั่ง +## Configuration +การตั้งค่าเฉพาะของแต่ละ service และการตั้งค่า route การตั้งค่า route ส่วนใหญ่จะทำคล้ายๆกัน ส่วนที่เป็น Frontend จะเป็นการเซ็ตโดเมน(URL)ของแต่ละโปรแกรม ส่วนที่เป็น Backend จะเป็นการรวมหลาย backend เข้าในโดเมนเดียวกันแต่อยู่คนละ Subfolder ซึ่งเป็นการรวม Microservice เข้าด้วยกัน -```bash -docker compose pull +### keycloak (bmahrms-id) +ใช้สำหรับการ login ในระบบ (Identity Server) การสือสารหลัง API Gateway จะเป็น https แบบ self-signed +```sh +cd bmahrms-service/keycloak_config +openssl genrsa -out keycloak.key 2048 +openssl req -new -x509 -sha256 -key keycloak.key -out keycloak.crt -days 3650 +cp keycloak.key keycloak.pem +cat keycloak.crt >> keycloak.pem +cd .. +``` +Keycloak Route +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: put_admin_api_key_here" -X PUT -d ' +{ + "id": "bmahrms-id", + "host": "bma-hrms-id.bangkok.go.th", + "uri": "/*", + "upstream": { + "scheme": "https", + "type": "roundrobin", + "nodes": { + "bmahrms-id:8443": 1 + } + } +}' +``` +### Portainer () +เป็นโปรแกรมสำหรับบริหารจัดการ container สามารถสิ่งเปิดปิดแก้ไขการทำงานของคอนเทนเนอร์ได้ เฉพาะผู้ดูแลระดับสูงถึงจะเข้าใช้งานส่วนนี้ + +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f2" -X PUT -d ' +{ + "id": "bmahrms-portainer", + "host": "bmahrms-portainer.bangkok.go.th", + "uri": "/*", + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-portainer:9000": 1 + } + } +}' +``` +### MySQL(bmahrms-postgres) +init_mysql/*.sql เป็นที่เก็บ SQL Script สำหรับสร้างฐานข้อมูลตั้งต้น +จะถูกเรียกใช้ครั้งแรกตอนเริ่มฐานข้อมูลเป็นข้อมูลตั้งต้นของระบบ +เนื่องจากไฟล์มีขนาดใหญ่หลายบรรทัดจะไม่ใส่ในเอกสารนี้ + +### Report Server +เป็น Microservice ใช้สำหรับการออกรายงาน ไม่จำเป็นต้องมี domain ของตัวเอง ให้เป็น path ในโดเมนที่มีอยู่ได้ ให้นำไฟล์ต้นแบบซึ่งสร้างจาก MS Word และ Excel มาไว้ที่โฟลเดอร์นี้ +report-server-template/docx/*.docx, report-server-template/xlsx/*.xlsx +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: put_admin_api_key_here" -X PUT -d ' +{ + "id": "bmahrms-report-server", + "hosts": ["bma-hrms.bangkok.go.th","bma-hrms-user.bangkok.go.th"], + "uris": ["/api/v1/report-template/*"], + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-report-server:80": 1 + } + } +}' ``` -6. ระบบจะ pull Docker Image ทั้งหมดตามที่เราประกาศไว้ใน File Docker Compose -7. หลังจากนั้นรันคำสั่งนี้ เพื่อให้ทำการ Reload Docker Container เพื่อให้ระบบทำการ Update มาใช้ Image Version ล่าสุด +### MiniO -```bash -docker compose up -d +Object Storage ใช้เพื่อเก็บไฟล์ของระบบถูกใช้โดย HRMS และ EDM +Route จะมีส่วน API กับ console การทำ route จะให้ console อยู่ใต้ subfoler https://domain/console +ในการติดตั้งบน production อาจจะไม่ได้อยู่ใน node เดียวกับ hrms และ apisix ดังนั้นควรอ้างเป็นโดเมนเต็มแทน + +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: put_admin_api_key_here" -X PUT -d ' +{ + "id": "bmahrms-s3", + "host": "bma-hrms-s3.bangkok.go.th", + "uri": "/*", + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-s3:9000": 1 + } + } +}' +# test +curl -k -I https://bma-hrms-s3.bangkok.go.th/minio/health/live + +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: put_admin_api_key_here" -X PUT -d ' +{ + "id": "bmahrms-s3-console", + "host": "bma-hrms-s3.bangkok.go.th", + "uri": "/console/*", + "plugins": { + "proxy-rewrite": { + "regex_uri": ["^/console/(.*)","/$1"] + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-s3:9001": 1 + } + } +}' ``` -8. หากต้องการดู log แต่ละ service ให้ใช้คำสั่ง +### EDM (Enterprixe Document Management) +เป็นระบบจัดการเอกสารภายใน ประกอบไปด้วยโปรแกรมหลายตัว +- EDM ตัวโปรแกรมหลัก +- Elasticsearch ฐานข้อมูลดัชนีเอกสารเพื่อการค้นหาภาษาไทยแบบซับซ้อน อ้างผ่าน IP/PORT ไม่มี Route สู่ภายนอก +- Kibana ใน WebUI การจัดการ Elasticsearch มี Route ใช้เฉพาะนักพัฒนา +- RabbitMQ จัดการคิวงาน มี Route ใช้เฉพาะนักพัฒนา +- MiniO ใช้เพื่อเก็บไฟล์ต่างๆ มีหน้า console ใช้เฉพาะนักพัฒนา -```bash -docker compose logs -f {service name} +นอกเหนือจาก compose.yaml มีไฟล์คอนฟิกสองไฟล์ +```sh +nano edm_config/keycloak.json +nano elasticsearch_config/config.yaml ``` - -9. โดยการดู service name สามารถใช้คำสั่งนี้เพื่อทำการ List Container ขึ้นมา - -```bash -docker compose ps +edm_config/keycloak.json +```json +{ + "realm": "EDM", + "auth-server-url": "https://bma-hrms-id.bangkok.go.th/", + "ssl-required": "external", + "resource": "EDM-V1", + "public-client": true, + "confidential-port": 0 +} ``` - -10. ซึ่งระบบจะแสดง Container ทั้งหมดของ docker compose file นี้ขึ้นมาให้เราสามารถดูได้ - -```bash -NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS -bma-ehr-test1-bma-ehr-candidate-register-test1-1 docker.frappet.com/ehr/bma-ehr-recruit-exam:latest "/usr/local/bin/entr…" bma-ehr-candidate-register-test1 3 days ago Up 23 hours 80/tcp -bma-ehr-test1-bma-ehr-command-test1-1 docker.frappet.com/ehr/bma-ehr-command-service:latest "dotnet BMA.EHR.Comm…" bma-ehr-command-test1 12 hours ago Up 12 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-insignia-test1-1 docker.frappet.com/ehr/bma-ehr-insignia-service:latest "dotnet BMA.EHR.Insi…" bma-ehr-insignia-test1 12 hours ago Up 12 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-manual-test1-1 docker.frappet.com/ehr/bma-ehr-manual:latest "/docker-entrypoint.…" bma-ehr-manual-test1 3 days ago Up 23 hours 80/tcp -bma-ehr-test1-bma-ehr-metadata-test1-1 docker.frappet.com/ehr/bma-ehr-metadata-service:latest "dotnet BMA.EHR.Meta…" bma-ehr-metadata-test1 3 days ago Up 23 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-org-employee-test1-1 docker.frappet.com/ehr/bma-ehr-org-employee-service:latest "dotnet BMA.EHR.Orga…" bma-ehr-org-employee-test1 3 days ago Up 23 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-organization-test1-1 docker.frappet.com/ehr/bma-ehr-organization-service:latest "dotnet BMA.EHR.Orga…" bma-ehr-organization-test1 3 days ago Up 23 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-placement-test1-1 docker.frappet.com/ehr/bma-ehr-placement-service:latest "dotnet BMA.EHR.Plac…" bma-ehr-placement-test1 12 hours ago Up 12 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-probation-test1-1 docker.frappet.com/ehr/bma-ehr-node-service:version-1.0.1 "docker-entrypoint.s…" bma-ehr-probation-test1 About an hour ago Up About an hour 8080/tcp -bma-ehr-test1-bma-ehr-profile-test1-1 docker.frappet.com/ehr/bma-ehr-profile-service:latest "dotnet BMA-EHR-Prof…" bma-ehr-profile-test1 12 hours ago Up 12 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-qualifying-exam-cms-test1-1 docker.frappet.com/demo/qualifying-exam-cms:latest "docker-entrypoint.s…" bma-ehr-qualifying-exam-cms-test1 3 days ago Up 23 hours 80/tcp -bma-ehr-test1-bma-ehr-recruit-exam-test1-1 docker.frappet.com/ehr/bma-ehr-recruit-exam-service:latest "dotnet BMA.EHR.Recu…" bma-ehr-recruit-exam-test1 27 hours ago Up 23 hours 443/tcp, 0.0.0.0:4069->80/tcp, :::4069->80/tcp -bma-ehr-test1-bma-ehr-recruit-test1-1 docker.frappet.com/ehr/bma-ehr-recruit-service:latest "dotnet BMA.EHR.Recr…" bma-ehr-recruit-test1 27 hours ago Up 23 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-report-test1-1 docker.frappet.com/ehr/bma-ehr-report-service:latest "dotnet BMA.EHR.Repo…" bma-ehr-report-test1 3 days ago Up 23 hours 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-report-v2-test1-1 sha256:bad691df0d3914a2a50fc8c001d55c4ee8e59cd298537cc878a77bc7565c8993 "dotnet BMA.EHR.Repo…" bma-ehr-report-v2-test1 About an hour ago Up About an hour 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-retirement-test1-1 docker.frappet.com/ehr/bma-ehr-retirement-service:latest "dotnet BMA.EHR.Reti…" bma-ehr-retirement-test1 About an hour ago Up About an hour 80/tcp, 443/tcp -bma-ehr-test1-bma-ehr-test1-1 docker.frappet.com/ehr/bma-ehr-app:latest "/usr/local/bin/entr…" bma-ehr-test1 About an hour ago Up About an hour 80/tcp -bma-ehr-test1-bma-ehr-user-test1-1 docker.frappet.com/ehr/bma-ehr-user:latest "/usr/local/bin/entr…" bma-ehr-user-test1 27 hours ago Up 23 hours 80/tcp -bma-ehr-test1-bma-mongodb-test1-1 mongo:4.2.0 "docker-entrypoint.s…" bma-mongodb-test1 3 days ago Up 23 hours 0.0.0.0:4062->27017/tcp, :::4062->27017/tcp -bma-ehr-test1-bma-mysql-test1-1 mysql:8.0.17 "docker-entrypoint.s…" bma-mysql-test1 3 days ago Up 23 hours 33060/tcp, 0.0.0.0:4061->3306/tcp, :::4061->3306/tcp -``` - -11. หากเราต้องการ shell เข้าไปที่ตัว container สามารถใช้คำสั่งนี้ - -```bash -docker compose exec -it {service name} bash -``` - -## Production Environment (BMA Data Center) - -1. ใน DC จะเปลี่ยนมาใช้ฐานข้อมูล Oracle ซึ่งระบบได้มีการ build docker image ที่เป็น version สำหรับติดต่อฐานข้อมูล Oracle ไว้แล้ว -2. การติดตั้งระบบให้ทำการต่อ VPN เข้าไปที่ Network ของทางกทม.ก่อน -3. ทำการ ssh ไปที่ Application Server - -```bash -ssh psbehrapp01 -``` - -4. เมื่อ ssh เข้ามาแล้วจะพอหน้าจอแบบนี้ - -```bash -Linux vm-BMA04-00022 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -Last login: Tue Jun 4 09:25:07 2024 from 172.31.68.238 -administrator@vm-BMA04-00022:~$ -``` - -5. เข้าไปที่ folder docker/bma-ehr จะพบกับไฟล์ setup และ docker compose ที่ใช้สำหรับติดตั้งระบบ - -```bash -administrator@vm-BMA04-00022:~/docker/bma-ehr$ ls -la -total 96 -drwxr-xr-x 3 administrator administrator 4096 May 17 09:42 . -drwxr-xr-x 5 administrator administrator 4096 May 17 09:39 .. --rw-r--r-- 1 administrator administrator 1647 May 17 11:38 appsettings-command.json --rw-r--r-- 1 administrator administrator 2664 May 17 11:38 appsettings-discipline.json --rw-r--r-- 1 administrator administrator 1946 May 17 11:39 appsettings-insignia.json --rw-r--r-- 1 administrator administrator 2302 May 17 11:39 appsettings-leave.json --rw-r--r-- 1 administrator administrator 1683 May 17 10:20 appsettings-metadata.json --rw-r--r-- 1 administrator administrator 1763 May 17 10:28 appsettings-organization.json --rw-r--r-- 1 administrator administrator 1511 May 17 11:47 appsettings-org-employee.json --rw-r--r-- 1 administrator administrator 1946 May 17 11:47 appsettings-placement.json --rw-r--r-- 1 administrator administrator 1511 May 17 11:12 appsettings-profile.json --rw-r--r-- 1 administrator administrator 1919 May 17 11:47 appsettings-recruit-exam.json --rw-r--r-- 1 administrator administrator 1871 May 17 11:49 appsettings-recruit.json --rw-r--r-- 1 administrator administrator 2222 May 17 11:49 appsettings-report.json --rw-r--r-- 1 administrator administrator 2296 May 17 11:49 appsettings-report-v2.json --rw-r--r-- 1 administrator administrator 2048 May 17 11:49 appsettings-retirement.json --rw-r--r-- 1 administrator administrator 28113 May 21 12:39 docker-compose.yml -drwxr-xr-x 3 administrator administrator 4096 May 17 09:42 wwwroot -administrator@vm-BMA04-00022:~/docker/bma-ehr$ -``` - -6. รายละเอียดใน docker-compose.yml มีดังนี้ - +elasticsearch_config/config.yaml ```yaml -administrator@vm-BMA04-00022:~/docker/bma-ehr$ ls -la -total 96 -drwxr-xr-x 3 administrator administrator 4096 May 17 09:42 . -drwxr-xr-x 5 administrator administrator 4096 May 17 09:39 .. --rw-r--r-- 1 administrator administrator 1647 May 17 11:38 appsettings-command.json --rw-r--r-- 1 administrator administrator 2664 May 17 11:38 appsettings-discipline.json --rw-r--r-- 1 administrator administrator 1946 May 17 11:39 appsettings-insignia.json --rw-r--r-- 1 administrator administrator 2302 May 17 11:39 appsettings-leave.json --rw-r--r-- 1 administrator administrator 1683 May 17 10:20 appsettings-metadata.json --rw-r--r-- 1 administrator administrator 1763 May 17 10:28 appsettings-organization.json --rw-r--r-- 1 administrator administrator 1511 May 17 11:47 appsettings-org-employee.json --rw-r--r-- 1 administrator administrator 1946 May 17 11:47 appsettings-placement.json --rw-r--r-- 1 administrator administrator 1511 May 17 11:12 appsettings-profile.json --rw-r--r-- 1 administrator administrator 1919 May 17 11:47 appsettings-recruit-exam.json --rw-r--r-- 1 administrator administrator 1871 May 17 11:49 appsettings-recruit.json --rw-r--r-- 1 administrator administrator 2222 May 17 11:49 appsettings-report.json --rw-r--r-- 1 administrator administrator 2296 May 17 11:49 appsettings-report-v2.json --rw-r--r-- 1 administrator administrator 2048 May 17 11:49 appsettings-retirement.json --rw-r--r-- 1 administrator administrator 28113 May 21 12:39 docker-compose.yml -drwxr-xr-x 3 administrator administrator 4096 May 17 09:42 wwwroot -administrator@vm-BMA04-00022:~/docker/bma-ehr$ +network.host: 0.0.0.0 +s3.client.default.endpoint: bma-hrms-s3.bangkok.go.th + ``` - -7. หลังจากนั้นให้เข้าไปที่ folder ของตัวระบบ Production แล้วรันคำสั่ง - -```bash -docker compose pull +EDM Route +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f2" -X PUT -d ' +{ + "id": "bmahrms-edm", + "host": "bma-hrms-edm.bangkok.go.th", + "uri": "/*", + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-edm:80": 1 + } + } +}' ``` +Kibana Route +เป็น UI สำหรับ Elasticsearch สามารถใช้แบบ HTTP ตรงๆได้ผ่าน VPN ถ้า โดยทั่วไปใช้ผ่านเน็ตเวิร์กภายใน API gateway จะช่วยทำ Basic Authentication และ https ให้ควรใช้ ใช้ภายในเสำหรับนักพัฒนาเท่านั้น +```sh +curl "http://127.0.0.1:9180/apisix/admin/routes" \ +-H "X-API-KEY: put_admin_api_key_here" -X PUT -d ' +{ + "id": "bmahrms-kibana", + "host": "bma-hrms-kibana.bangkok.go.th", + "uri": "/*", + "plugins": { + "basic-auth": {} + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "bmahrms-kibana:5601": 1 + } + } +}' +# Basic Authentication +curl http://127.0.0.1:9180/apisix/admin/consumers \ +-H 'X-API-KEY: put_admin_api_key_here' -X PUT -d ' +{ + "username": "admin", + "plugins": { + "basic-auth": { + "username": "admin", + "password": "kibana-password-here" + } + } +}' -8. ระบบจะ pull Docker Image ทั้งหมดตามที่เราประกาศไว้ใน File Docker Compose -9. หลังจากนั้นรันคำสั่งนี้ เพื่อให้ทำการ Reload Docker Container เพื่อให้ระบบทำการ Update มาใช้ Image Version ล่าสุด - -```bash -docker compose up -d -``` - -10. หากต้องการดู log แต่ละ service ให้ใช้คำสั่ง - -```bash -docker compose logs -f {service name} -``` - -11. โดยการดู service name สามารถใช้คำสั่งนี้เพื่อทำการ List Container ขึ้นมา - -```bash -docker compose ps -``` - -12. ซึ่งระบบจะแสดง Container ทั้งหมดของ docker compose file นี้ขึ้นมาให้เราสามารถดูได้ - -```bash -administrator@vm-BMA04-00022:~/docker/bma-ehr$ docker compose ps -WARN[0000] /home/administrator/docker/bma-ehr/docker-compose.yml: `version` is obsolete -NAME IMAGE COMMAND SERVICE CREATED STATUS - PORTS -bma-ehr-checkin-oracle docker.frappet.com/ehr/bma-ehr-checkin:latest "/usr/local/bin/entr…" bma-ehr-checkin-oracle 2 weeks ago Up 2 weeks - 80/tcp -bma-ehr-command-oracle docker.frappet.com/ehr/oracle/bma-ehr-command-service:latest "dotnet BMA.EHR.Comm…" bma-ehr-command-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-discipline-oracle docker.frappet.com/ehr/oracle/bma-ehr-discipline-service:latest "dotnet BMA.EHR.Disc…" bma-ehr-discipline-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-evaluation-oracle docker.frappet.com/ehr/oracle/bma-ehr-evaluation-service:latest "docker-entrypoint.s…" bma-ehr-evaluation-oracle 2 weeks ago Up 2 weeks - 0.0.0.0:14039->8082/tcp, :::14039->8082/tcp -bma-ehr-insignia-oracle docker.frappet.com/ehr/oracle/bma-ehr-insignia-service:latest "dotnet BMA.EHR.Insi…" bma-ehr-insignia-oracle 2 weeks ago Up 2 weeks - 443/tcp, 0.0.0.0:15031->80/tcp, :::15031->80/tcp -bma-ehr-kpi-oracle docker.frappet.com/ehr/oracle/bma-ehr-kpi-service:latest "docker-entrypoint.s…" bma-ehr-kpi-oracle 2 weeks ago Restarting (1) 59 seconds ago -bma-ehr-leave-oracle docker.frappet.com/ehr/oracle/bma-ehr-leave-service:latest "dotnet BMA.EHR.Leav…" bma-ehr-leave-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-metadata-oracle docker.frappet.com/ehr/oracle/bma-ehr-metadata-service:latest "dotnet BMA.EHR.Meta…" bma-ehr-metadata-oracle 2 weeks ago Up 2 weeks - 443/tcp, 0.0.0.0:14065->80/tcp, :::14065->80/tcp -bma-ehr-oracle docker.frappet.com/ehr/bma-ehr-app:latest "/usr/local/bin/entr…" bma-ehr-oracle 2 weeks ago Up 2 weeks - 80/tcp -bma-ehr-org-employee-oracle docker.frappet.com/ehr/oracle/bma-ehr-org-employee-service:latest "dotnet BMA.EHR.Orga…" bma-ehr-org-employee-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-org-oracle docker.frappet.com/ehr/oracle/bma-ehr-org-service:latest "docker-entrypoint.s…" bma-ehr-org-oracle 2 weeks ago Up 2 weeks - 0.0.0.0:4038->8081/tcp, :::4038->8081/tcp -bma-ehr-placement-oracle docker.frappet.com/ehr/oracle/bma-ehr-placement-service:latest "dotnet BMA.EHR.Plac…" bma-ehr-placement-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-probation-oracle docker.frappet.com/ehr/oracle/bma-ehr-node-service:latest "docker-entrypoint.s…" bma-ehr-probation-oracle 13 days ago Up 13 days - 8080/tcp -bma-ehr-profile-oracle docker.frappet.com/ehr/oracle/bma-ehr-profile-service:latest "dotnet BMA-EHR-Prof…" bma-ehr-profile-oracle 2 weeks ago Up 2 weeks - 443/tcp, 0.0.0.0:14066->80/tcp, :::14066->80/tcp -bma-ehr-publish-oracle docker.frappet.com/ehr/bma-ehr-publish:latest "/usr/local/bin/entr…" bma-ehr-publish-oracle 2 weeks ago Up 2 weeks - 80/tcp -bma-ehr-report-oracle docker.frappet.com/ehr/oracle/bma-ehr-report-service:latest "dotnet BMA.EHR.Repo…" bma-ehr-report-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-report-v2-oracle docker.frappet.com/ehr/oracle/bma-ehr-report-v2-service:latest "dotnet BMA.EHR.Repo…" bma-ehr-report-v2-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-retirement-oracle docker.frappet.com/ehr/oracle/bma-ehr-retirement-service:latest "dotnet BMA.EHR.Reti…" bma-ehr-retirement-oracle 2 weeks ago Up 2 weeks - 80/tcp, 443/tcp -bma-ehr-salary-oracle docker.frappet.com/ehr/oracle/bma-ehr-salary-service:latest "docker-entrypoint.s…" bma-ehr-salary-oracle 2 weeks ago Up 2 weeks - 0.0.0.0:14040->8081/tcp, :::14040->8081/tcp -bma-ehr-user-oracle docker.frappet.com/ehr/bma-ehr-user:latest "/usr/local/bin/entr…" bma-ehr-user-oracle 2 weeks ago Up 2 weeks - 80/tcp -bma-mongodb-oracle mongo:4.2.0 "docker-entrypoint.s…" bma-mongodb-oracle 2 weeks ago Up 2 weeks - 0.0.0.0:14062->27017/tcp, :::14062->27017/tcp -administrator@vm-BMA04-00022:~/docker/bma-ehr$ -``` +``` \ No newline at end of file