컨테이너 재시작 - discourse가 재설치를 시도합니다

@rosscdh와 나눈 부수적인 대화에서 그의 최종 목표가 Kubernetes 기반의 Discourse라는 것을 알게 되었습니다. 여기서는 해당 구성을 지원하지 않습니다. Docker/Kubernetes 관련 방식에 대해 유효한 비판이 있을 수 있지만, 자체 호스팅 환경에서의 사용 편의성을 위해 launcher를 통해 이 방식을 선택했습니다.

이 주제를 다시 열었지만, 예의 있고 건설적인 대화를 부탁드립니다.

하지만 ./launcher가 개발된 이후에야 그런 것이 생겼습니다. :wink:

k8s나 유사한 환경으로 배포하고 싶다면, 저는 런처를 사용해 이미지를 빌드한 후 어딘가에 푸시하고, k8ts가 해당 이미지를 실행하도록 합니다. 런처는 업그레이드 시 데이터베이스 마이그레이션과 같은 작업을 수행하므로, 그 동작 방식을 주의 깊게 살펴봐야 합니다.

감사합니다.

목표는 더 Docker 스타일처럼 만들어서 kube에서도, 혹은 독립 컨테이너로 Docker만 사용하는 환경에서도 실행할 수 있게 하는 것입니다.

런처를 사용해 2GB가 넘는(4개 플러그인, 한계 때문에 6개는 불가) 이미지를 생성하는 데 성공했습니다.

또한 docker-compose를 구성하여 이제 깔끔한 런북(runbook)이 되었습니다.
GlobalSettings에 익숙하고, application.rb와 routes.rb를 약간 수정하여 커스터마이징을 마운트하는 방식으로 진행했습니다.

version: '3'

networks:
  discourse-net:

services:
  mailhog:
    image: mailhog/mailhog:latest
    networks:
      - discourse-net
    ports:
      - 8025:8025

  postgres:
    image: postgres:9.6
    networks:
      - discourse-net
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: discourse
      POSTGRES_DB: discourse

  redis:
    image: redis:alpine
    networks:
      - discourse-net

  discourse:
    image: discourse-monkey:latest
    working_dir: /var/www/discourse
    command: bash /var/www/discourse/entrypoint.sh
    # ports:
    #   - 3000:3000 # use the nginx entrypoint
    networks:
      - discourse-net
    volumes:
      - ./entrypoint.sh:/var/www/discourse/entrypoint.sh
      - ./config/unicorn.rb:/var/www/discourse/config/unicorn.rb
      - ./config/application.rb:/var/www/discourse/config/application.rb
      - ./envs/production.rb:/var/www/discourse/config/environments/production.rb
      - ./overrides/routes.rb:/var/www/discourse/config/routes.rb
      - ./generated/public/assets:/var/www/discourse/public/assets
      - ./generated/public/images:/var/www/discourse/public/images
      - ./generated/public/uploads:/var/www/discourse/public/uploads
      - ./generated/public/javascripts:/var/www/discourse/public/javascripts
      - ./generated/public/svg-sprite:/var/www/discourse/public/svg-sprite

    environment:
      LANG: en_US.UTF-8
      DISCOURSE_DEFAULT_LOCALE: en
      RAILS_ENV: production
      ## How many concurrent web requests are supported? Depends on memory and CPU cores.
      ## will be set automatically by bootstrap based on detected CPUs, or you can override
      UNICORN_WORKERS: 3

      ## TODO: The domain name this Discourse instance will respond to
      DISCOURSE_HOSTNAME: discuss.monkey.tech:3001
      DOCKER_USE_HOSTNAME: "true"

      ## Uncomment if you want the container to be started with the same
      ## hostname (-h option) as specified above (default "$hostname-$config")
      #DOCKER_USE_HOSTNAME: true

      ## TODO: List of comma delimited emails that will be made admin and developer
      ## on initial signup example 'user1@example.com,user2@example.com'
      DISCOURSE_DEVELOPER_EMAILS: 'me@example.com,you@example.com'

      ## TODO: The SMTP mail server used to validate new accounts and send notifications
      # SMTP ADDRESS, username, and password are required
      # WARNING the char '#' in SMTP password can cause problems!
      DISCOURSE_SMTP_ADDRESS: mailhog
      #DISCOURSE_SMTP_PORT: 587
      DISCOURSE_SMTP_USER_NAME: mailhog
      DISCOURSE_SMTP_PASSWORD: password
      #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)

      ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
      #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

      ## TODO: configure connectivity to the databases
      # DISCOURSE_DB_SOCKET: ''
      DISCOURSE_DB_HOST: postgres
      DISCOURSE_DB_USERNAME: discourse
      DISCOURSE_DB_PASSWORD: password
      DISCOURSE_REDIS_HOST: redis

      ## The http or https CDN address for this Discourse instance (configured to pull)
      ## see https://meta.discourse.org/t/14857 for details
      DISCOURSE_CDN_URL: http://discuss.monkey.tech:3001
      DISCOURSE_SERVE_STATIC_ASSETS: "true"

      SKIP_ENFORCE_HOSTNAME: '0'
      ENABLE_ASSETS_PIPELINE: '0'
      ENABLE_DB_MIGRATE: '0'

      DISCOURSE_ENABLE_CORS: 'false'
      DISCOURSE_CORS_ORIGIN: '*'
      #SKIP_DB_AND_REDIS: '1'

  nginx:
    image: fholzer/nginx-brotli
    # command: /bin/sh -c "envsubst < /etc/nginx/conf.d/discourse.template.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" 
    ports:
      - 3001:80
    depends_on:
      - discourse
    networks:
      - discourse-net
    volumes:
      - ./config/nginx.application.conf:/etc/nginx/conf.d/default.conf
      - ./generated/public:/var/www/discourse/public
      - ./generated/nginx/cache:/var/nginx/cache

매우 잘 작동하며, 모든 트래픽은 nginx를 통해 라우팅되고, 이는 assets:precompile 출력도 공유합니다.

다음 단계는 이미지를 호출하여 assets와 db:migrate를 “요청 시(on demand)” 사전 컴파일하거나, 단순히 exec를 사용하여 동일한 작업을 수행하는 것입니다(해당 항목들은 자주 변경되지 않으므로). 그리고 2.6GB인 이 이미지 크기를 줄일 수 있는지 확인해볼 예정입니다.

앞서 언급했듯이, pup 기능성은 괜찮고 제공하는 가치를 인정합니다. 하지만 실행 위치에서 빌드하고 sudo 전략을 사용하는 방식에 대해서는 꽤 많은 의구심이 있습니다. (이것은 저나 제가 아는 누구의 일반적인 작업 방식이 아닙니다) 보통 이미지는 독립적으로 빌드된 후 다른 곳(kube, saltstack, nomad, docker-compose)에 배포됩니다.

db와 redis를 비활성화하고, 빌드 시에도 실제로 redis와 db를 비활성화하며, precompile도 비활성화해야 하는 특정 항목, 오버라이드 및 설정이 있으므로 sample/kube.yml과 applications/kubernetes.template.yml을 추가하는 PR을 준비하고 있습니다. 만약 관심이 있으시다면 말씀해 주세요.

흥미로운 경험이었으며, 올려주셔서 감사합니다.

픽스처(fixtures)와 관련하여 작은 이상함이 하나 있습니다(여러 번 migrate를 호출했기 때문일 수 있음)
첨부된 이미지를 참조하세요

docker-compose는 "fig"라는 도구를 기반으로 개발된 것으로 알고 있습니다.