-
-
Save designervoid/424f6e1c14a982d210d39422e966f23c to your computer and use it in GitHub Desktop.
| # my_frontend/docker-compose.yml | |
| version: '3.7' | |
| services: | |
| my_frontend: | |
| container_name: my_frontend | |
| networks: | |
| - my_network | |
| restart: unless-stopped | |
| security_opt: | |
| - no-new-privileges:true | |
| build: . | |
| env_file: | |
| - .env | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.routers.frontend.entrypoints=https" | |
| - "traefik.http.routers.frontend.rule=Host(`domain.com`) && (PathPrefix(`/frontend`) || PathPrefix(`/_nuxt`))" | |
| - "traefik.http.routers.frontend.tls.certresolver=letsEncrypt" | |
| - "traefik.http.services.frontend.loadbalancer.server.port=8090" | |
| networks: | |
| my_network: | |
| external: true | |
| name: "my_network" |
| # reverse-proxy/docker-compose.yml | |
| version: '3.7' | |
| services: | |
| traefik: | |
| image: traefik:v2.2 | |
| container_name: traefik | |
| command: | |
| - "--log.level=DEBUG" | |
| networks: | |
| - my_network | |
| restart: unless-stopped | |
| security_opt: | |
| - no-new-privileges:true | |
| ports: | |
| - 80:80 | |
| - 443:443 | |
| - 8090:8090 | |
| volumes: | |
| - /etc/localtime:/etc/localtime:ro | |
| - /var/run/docker.sock:/var/run/docker.sock:ro | |
| - ./data/traefik.yml:/traefik.yml:ro | |
| - ./data/custom/:/custom/:ro | |
| - ./data/acme.json:/acme.json | |
| labels: | |
| - "traefik.enable=true" | |
| - "traefik.http.routers.traefik.entrypoints=https" | |
| - "traefik.http.routers.traefik.rule=Host(`domain.com`)" | |
| - "traefik.http.routers.traefik.tls=true" | |
| - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt" | |
| - "traefik.http.routers.traefik.service=api@internal" | |
| - "traefik.http.services.traefik.loadbalancer.server.port=888" | |
| # Auth Middleware | |
| - "traefik.http.middlewares.traefik-auth.basicauth.users=your_username_here:your_password_here" | |
| - "traefik.http.routers.traefik.middlewares=traefik-auth" | |
| networks: | |
| my_network: | |
| external: true | |
| name: "my_network" |
| # my_frontend/Dockerfile | |
| ### STAGE 1: Build ### | |
| FROM node:latest as build | |
| RUN mkdir /usr/src/app | |
| WORKDIR /usr/src/app | |
| ENV PATH /usr/src/app/node_modules/.bin:$PATH | |
| COPY package.json /usr/src/app/package.json | |
| RUN npm install --silent | |
| COPY . /usr/src/app | |
| RUN npm run generate | |
| ### STAGE 2: NGINX ### | |
| FROM nginx:stable-alpine | |
| COPY --from=build /usr/src/app/docker /usr/share/nginx/html/ | |
| RUN rm /etc/nginx/conf.d/* | |
| COPY nginx/main.conf /etc/nginx/conf.d/ | |
| EXPOSE 8090 | |
| CMD ["nginx", "-g", "daemon off;"] |
| # reverse-proxy/data/custom/host.yml | |
| http: | |
| routers: | |
| host: | |
| entryPoints: | |
| - https | |
| service: service-host | |
| rule: Host(`domain.com`) | |
| tls: | |
| certResolver: letsEncrypt | |
| services: | |
| service-host: | |
| loadBalancer: | |
| servers: | |
| - url: "http://127.0.0.1:8080" | |
| passHostHeader: true |
| # my_frontend/nginx/main.conf | |
| map $sent_http_content_type $expires { | |
| "text/html" epoch; | |
| "text/html; charset=utf-8" epoch; | |
| default off; | |
| } | |
| server { | |
| listen 8090; | |
| server_name localhost; | |
| charset utf-8; | |
| client_max_body_size 10M; | |
| gzip on; | |
| gzip_types text/plain application/xml text/css application/javascript; | |
| gzip_min_length 1000; | |
| #charset koi8-r; | |
| # access_log logs/host.access.log main; | |
| location / { | |
| absolute_redirect off; | |
| root /usr/share/nginx/html/dist; | |
| try_files $uri $uri/ /index.html; | |
| } | |
| } |
| # reverse-proxy/data/traefik.yml | |
| api: | |
| dashboard: true | |
| entryPoints: | |
| http: | |
| address: ":80" | |
| https: | |
| address: ":443" | |
| http: | |
| routers: | |
| http-catchall: | |
| rule: hostregexp(`{any:.+}`) | |
| entrypoints: | |
| - http | |
| middlewares: | |
| - redirect-to-https | |
| middlewares: | |
| redirect-to-https: | |
| redirectScheme: | |
| scheme: https | |
| permanent: true | |
| port: "443" | |
| providers: | |
| docker: | |
| endpoint: "unix:///var/run/docker.sock" | |
| exposedByDefault: false | |
| file: | |
| directory: /custom | |
| watch: true | |
| certificatesResolvers: | |
| letsEncrypt: | |
| acme: | |
| email: [email protected] | |
| storage: acme.json | |
| #caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" | |
| httpChallenge: | |
| entryPoint: http |
Как работает один узел приложения
Для корректной работы требуется установить Docker, Docker Compose, а также выставить права файлу /data/acme.json:
$ chmod 600 /data/acme.jsonЗатем надо создать Docker Network:
$ docker network create main_networkНа эту схему требуется смотреть справа налево. Входной точкой в приложение является HTTP:80 или HTTPS:443, в зависимости от того, какой протокол явно выбрал клиент
http://domain.com или https://domain.com при вводе домена в адресную строку. Если клиент подключается через незащищённое
http соединение (80 порт), мы проксируем его на защищённое
https соединение (443 порт). При неявном выборе протокола domain.com - клиента проксирует на защищённое соединение. Чтобы сервисы тоже общались между собой через https - необходимо добавить несколько полей метаданных в конфигурационный файл Docker. Метаданные записываются в поле labels, конфигурационного файла docker-compose-frontend.yml. Все сервисы Docker Compose связаны между собой единой Docker Network, external означает то, что сеть внешняя. Перед запуском приложения её необходимо создать вручную (один раз), дальше он всегда будет присоединяться к этой сети:
Архитектура построена на основе статьи - https://habr.com/ru/post/508636/



Все приложение базируется на Traefik Reverse Proxy. В данном приложении - это единственный прокси-сервис, который смотрит в глобальную сеть.

В приложении используются сервисы Traefik и Frontend.