diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9329f1f43c..61c6cb43b0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,11 +4,45 @@ on: push: branches: - develop + - master + tags: + - 'v*' jobs: - deploy: + create-app-env: + runs-on: ubuntu-latest + timeout-minutes: 60 + outputs: + image-tag: ${{ steps.output-app-env.outputs.image-tag }} + eb-environment-name: ${{ steps.output-app-env.outputs.eb-environment-name }} + + steps: + - uses: actions/checkout@v2 + + - name: Set env to staging + id: set-env-staging + if: endsWith(github.ref, 'heads/develop') + run: | + echo "IMAGE_TAG_PREFIX=staging" >> $GITHUB_ENV + echo "EB_ENVIRONMENT_NAME=staging" >> $GITHUB_ENV + + - name: Set env to production + id: set-env-production + if: endsWith(github.ref, 'heads/master') || contains(github.ref, 'tags/v') + run: | + echo "IMAGE_TAG_PREFIX=production" >> $GITHUB_ENV + echo "EB_ENVIRONMENT_NAME=production" >> $GITHUB_ENV + + - name: Output App Env + id: output-app-env + run: | + echo "::set-output name=image-tag::${IMAGE_TAG_PREFIX}-${GITHUB_SHA::8}" + echo "::set-output name=eb-environment-name::${EB_ENVIRONMENT_NAME}" + + build: runs-on: ubuntu-latest timeout-minutes: 1200 + needs: create-app-env steps: - uses: actions/checkout@v2 @@ -25,14 +59,51 @@ jobs: uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR + if: endsWith(github.ref, 'heads/master') || endsWith(github.ref, 'heads/develop') env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} - IMAGE_TAG: staging + IMAGE_TAG: ${{ needs.create-app-env.outputs.image-tag }} run: | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + deploy: + runs-on: ubuntu-latest + timeout-minutes: 1800 + if: endsWith(github.ref, 'heads/develop') || contains(github.ref, 'tags/v') + needs: + - create-app-env + - build + + steps: + - uses: actions/checkout@v2 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Check if ECR Image exists with tag + if: contains(github.ref, 'tags/v') + env: + IMAGE_TAG: ${{ needs.create-app-env.outputs.image-tag }} + ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} + run: | + EXIT_CODE=0 + aws ecr describe-images --repository-name=$ECR_REPOSITORY --image-ids=imageTag=$IMAGE_TAG 2> /dev/null || EXIT_CODE=$? + + if [[ $EXIT_CODE != 0 ]]; then + echo "${IMAGE_TAG} image tag not found" + exit 1 + fi + - uses: actions/setup-python@master with: python-version: "3.7" @@ -42,13 +113,12 @@ jobs: - name: Deploy to Elastic Beanstalk env: + EB_ENVIRONMENT_NAME: ${{ needs.create-app-env.outputs.eb-environment-name }} + IMAGE_TAG: ${{ needs.create-app-env.outputs.image-tag }} ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} - IMAGE_TAG: staging - EB_ENVIRONMENT_NAME: staging run: | - cp -r .ebextensions/ deployments/.ebextensions cd deployments - sed -i -e "s|t2.small|t2.micro|g" .ebextensions/00_options.config + cp ${EB_ENVIRONMENT_NAME}/00_options.config .ebextensions/00_options.config sed -i -e "s|{RepositoryName}|$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG|g" Dockerrun.aws.json - eb deploy ${EB_ENVIRONMENT_NAME} + eb deploy ${EB_ENVIRONMENT_NAME} --timeout=20 diff --git a/.platform/nginx/nginx.conf b/.platform/nginx/nginx.conf deleted file mode 100644 index 07d45ff72d..0000000000 --- a/.platform/nginx/nginx.conf +++ /dev/null @@ -1,117 +0,0 @@ -# For more information on configuration, see: -# * Official English Documentation: http://nginx.org/en/docs/ -# * Official Russian Documentation: http://nginx.org/ru/docs/ - -user nginx; -worker_processes auto; -error_log /var/log/nginx/error.log; -pid /var/run/nginx.pid; - -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. -include /usr/share/nginx/modules/*.conf; - -events { - worker_connections 1024; -} - -http { - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - server_tokens off; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 4096; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - # Load modular configuration files from the /etc/nginx/conf.d directory. - # See http://nginx.org/en/docs/ngx_core_module.html#include - # for more information. - include /etc/nginx/conf.d/*.conf; - - index index.html index.htm; - - server { - listen 80; - listen [::]:80; - server_name _; - root /usr/share/nginx/html; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - # redirect server error pages to the static page /40x.html - # - error_page 404 /404.html; - location = /40x.html { - } - - # redirect server error pages to the static page /50x.html - # - error_page 500 502 503 504 /50x.html; - location = /50x.html { - } - - # proxy the PHP scripts to Apache listening on 127.0.0.1:80 - # - #location ~ \.php$ { - # proxy_pass http://127.0.0.1; - #} - - # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 - # - #location ~ \.php$ { - # root html; - # fastcgi_pass 127.0.0.1:9000; - # fastcgi_index index.php; - # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; - # include fastcgi_params; - #} - - # deny access to .htaccess files, if Apache's document root - # concurs with nginx's one - # - #location ~ /\.ht { - # deny all; - #} - } - -# Settings for a TLS enabled server. -# -# server { -# listen 443 ssl http2; -# listen [::]:443 ssl http2; -# server_name _; -# root /usr/share/nginx/html; -# -# ssl_certificate "/etc/pki/nginx/server.crt"; -# ssl_certificate_key "/etc/pki/nginx/private/server.key"; -# # It is *strongly* recommended to generate unique DH parameters -# # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048 -# #ssl_dhparam "/etc/pki/nginx/dhparams.pem"; -# ssl_session_cache shared:SSL:1m; -# ssl_session_timeout 10m; -# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -# ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP; -# ssl_prefer_server_ciphers on; -# -# # Load configuration files for the default server block. -# include /etc/nginx/default.d/*.conf; -# -# error_page 404 /404.html; -# location = /40x.html { -# } -# -# error_page 500 502 503 504 /50x.html; -# location = /50x.html { -# } -# } - -} diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 17781364bb..6a116b46c2 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -1,3 +1,72 @@ +# ※GUIでElastic Beanstalkの設定をいじらないでください。デプロイで戻ります。 + +Elastic Beanstalkの設定はコードで管理されています。 + +インスタンスタイプやオートスケールの設定が違うため、stagingとproductionで一部ファイルが別です。それ以外の共通の設定は同じファイルを使っているので気を付けて下さい。 + +共通: [deployments/.ebextensions](deployments/.ebextensions) + +staging: [deployments/staging](deployments/staging) +production: [deployments/production](deployments/production) + +デプロイの際に上記の設定ファイルを元にデプロイが実行されます。コードでの設定がある場合、インフラも含め反映されます。 + +急ぎで、GUIで変更することはあると思います。しかし、GUIだけ変更してソースコードを変更しないと、デプロイの際に戻って事故の原因になります。なので、ソースコードに反映してください。 + +現状、認証情報等の非公開情報の設定方法が検討中なので、環境変数だけはGUIから設定してください。 + +GUIの設定とコードの書き方は、[公式](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-elasticbeanstalkapplicationenvironment)を参考にしてください。 + +# GitHubからデプロイ + +ワークフローの設定:[.github/workflows/deploy.yml](.github/workflows/deploy.yml) +デプロイの基本設定: [./deployments/](./deployments/) + +1. ECRにログイン +1. Dockerコンテナをbuild +1. short commit hashを含む環境ごとのタグで、ECRにDockerイメージをpush +1. elastic beanstalkに該当のイメージを指定してデプロイ + +Dockerイメージのタグ例: staging-dfasfste + +``` +[デプロイされる環境名]-[commit-hash] +``` + +## GitHubに必要な環境変数 + +- AWS_ACCESS_KEY_ID +- AWS_SECRET_ACCESS_KEY +- AWS_ECR_REPO_NAME + +## デプロイ手順 + +### production + +切り戻しを早くするため、masterマージの際、Dockerイメージは毎回buildします。 + +パイプラインが通ったのを確認後、git上でデプロイしたいコミットに、v○○とタグを打ちます。 +タグはvから始まる必要があります。すぐにeb deployが実行されます。 + +例: v1.0.0 + +### staging + +developブランチにpushすると自動でデプロイされます。 + +## 切り戻し + +### production + +普通にデプロイするのと同様に戻したい先commitに対してタグを打ちます。 +バグの場合、バグが発生したcommitの1つ前のcommitにたいしてタグを打ちます。 + +コンテナイメージはbuild済みなので、すぐにeb deployが実行されます。 + +### staging + +revetしてdevelopブランチにpushしてください。 + # CfJ Decidim AWS への Install(Beanstalk 編) ## 1. Install AWS tools and setup user @@ -21,11 +90,22 @@ bundle install ## 4. Elastic Beanstalk に 環境をセットアップする -[https://platoniq.github.io/decidim-install/decidim-aws/] 手順書の手順3に従って環境を作る +手順書の[手順3](https://platoniq.github.io/decidim-install/decidim-aws/#3-initialize-elasticbeanstalk)に従って環境を作る + + +[Dockerrun.aws.json](./deployment/Dockerrun.aws.json)の`{RepositoryName}`をECRのデプロイしたいイメージパスに修正。作成したい環境の設定をコピー。 + +[deployments/.elasticbeanstalk/config.yml](deployments/.elasticbeanstalk/config.yml)に設定があるので、基本的に何も聞かれないはずです。 -eb create を実施 ```bash +cd deployments + +// production +cp deployments/production/00_options.config .ebextensions/00_options.config +// staging(台数とかインスタンスタイプが小さい) +cp deployments/staging/00_options.config .ebextensions/00_options.config + eb create production ``` @@ -39,40 +119,33 @@ eb setenv SECRET_KEY_BASE=$(bin/rails secret) ## 5. Postgres データベースを作成する -EB コンソールの該当環境から、Configuration を選択、Database を選択し、Edit をする - 必要な設定を行い、DBを立ち上げる その後`eb deploy`を実行 -## 6. Healthcheck の条件を変更 - -`/` が301を返すので、一旦 301 でもOKにする - -Elastic Beanstalk の Configuration 画面で、Health Check を選び、Process の条件を 80 から 301 にする - -![img](https://i.imgur.com/VNZDQxA.png) -![img2](https://i.imgur.com/j595JQF.png) - -## 7. CNAME 設定とSSL設定 +## 6. CNAME 設定とSSL設定 Elastic Beanstalk のインスタンスをAレコードとして割り当てる ロードバランサの設定をする(手順[6.2 Configure SSL](https://platoniq.github.io/decidim-install/decidim-aws/#62-configure-ssl)) -## 8. 最初のユーザを作る +## 7. 最初のユーザを作る [6.3 Create the first admin user](https://platoniq.github.io/decidim-install/decidim-aws/#63-create-the-first-admin-user) に従う(root で) -## 9. SES の設定をする +## 8. SES の設定をする [6.4 Setup email](https://platoniq.github.io/decidim-install/decidim-aws/#64-setup-email) -## 10. REDIS の設定をする +## 9. REDIS の設定をする [6.5 Configure the job system with Sidekiq and Redis](https://platoniq.github.io/decidim-install/decidim-aws/#65-configure-the-job-system-with-sidekiq-and-redis) -## 11. S3 の設定をする +stagingはcloud formationで作成しています。 + +[.cloudformation/elastic_cache.yml](.cloudformation/elastic_cache.yml) + +## 10. S3 の設定をする [6.6 File storage](https://platoniq.github.io/decidim-install/decidim-aws/#66-file-storage) diff --git a/DEVLOPMENT.md b/DEVELOPMENT.md similarity index 100% rename from DEVLOPMENT.md rename to DEVELOPMENT.md diff --git a/Dockerfile b/Dockerfile index 3e3d20fed5..82a35296fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,8 +33,9 @@ ENV LANG=C.UTF-8 \ BUNDLER_VERSION=1.17.3 \ APP_HOME=/app \ RAILS_ENV=${RAILS_ENV} \ - SECRET_KEY_BASE=placeholder \ - RAILS_SERVE_STATIC_FILES=true + RAILS_LOG_TO_STDOUT=true \ + RAILS_SERVE_STATIC_FILES=true \ + SECRET_KEY_BASE=placeholder WORKDIR $APP_HOME diff --git a/app/views/decidim/application/_collection.html.erb b/app/views/decidim/application/_collection.html.erb new file mode 100644 index 0000000000..f50093c939 --- /dev/null +++ b/app/views/decidim/application/_collection.html.erb @@ -0,0 +1,20 @@ +<% unless attachment_collection.unused? %> +
+ <%= icon "caret-right", class: "icon--small", role: "img", "aria-hidden": true %>  + <%= translated_attribute(attachment_collection.name) %> + + <% attachment_collection_documents_count = attachment_collection.attachments.select(&:document?).count %> + (<%= attachment_collection_documents_count %> <%= t("decidim.application.collection.documents", count: attachment_collection_documents_count) %>) + + +
+

<%= translated_attribute(attachment_collection.description) %>

+ +
+ <% documents.each do |document| %> + <%= render partial: "decidim/application/document.html", locals: { document: document } %> + <% end %> +
+
+
+<% end %> diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 4ab760dd23..a54c1f24a7 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -151,6 +151,10 @@ ja: sortition_cancel_author: deleted: 退会者 verifications: + authorizations: + first_login: + actions: + user_extension_authorization_handler: ユーザー拡張属性対応用 postal_letter: admin: pending_authorizations: diff --git a/config/newrelic.yml b/config/newrelic.yml index ff79dd7e3b..36f3e79c2c 100644 --- a/config/newrelic.yml +++ b/config/newrelic.yml @@ -24,9 +24,11 @@ common: &default_settings # To disable the agent regardless of other settings, uncomment the following: # agent_enabled: false - # Logging level for log/newrelic_agent.log + # Logging level log_level: info + log_file_path: STDOUT + # Environment-specific settings are in this section. # RAILS_ENV or RACK_ENV (as appropriate) is used to determine the environment. diff --git a/.ebextensions/01_swap.config b/deployments/.ebextensions/01_swap.config similarity index 100% rename from .ebextensions/01_swap.config rename to deployments/.ebextensions/01_swap.config diff --git a/.ebextensions/02_packages.config b/deployments/.ebextensions/02_packages.config similarity index 100% rename from .ebextensions/02_packages.config rename to deployments/.ebextensions/02_packages.config diff --git a/.ebextensions/03_sidekiq.config b/deployments/.ebextensions/03_sidekiq.config similarity index 100% rename from .ebextensions/03_sidekiq.config rename to deployments/.ebextensions/03_sidekiq.config diff --git a/deployments/.ebignore b/deployments/.ebignore index c8d44f3bba..22c6c3d810 100644 --- a/deployments/.ebignore +++ b/deployments/.ebignore @@ -1 +1,3 @@ ./elasticbeanstalk +/staging +/production diff --git a/.ebextensions/00_options.config b/deployments/production/00_options.config similarity index 65% rename from .ebextensions/00_options.config rename to deployments/production/00_options.config index 3fae7a39b4..beb8820c01 100644 --- a/.ebextensions/00_options.config +++ b/deployments/production/00_options.config @@ -4,25 +4,29 @@ option_settings: EC2KeyName : "aws-eb" RootVolumeSize : "100" RootVolumeType : "gp2" + "aws:autoscaling:asg": + MinSize: 3 + MaxSize: 5 "aws:autoscaling:updatepolicy:rollingupdate": MaxBatchSize: "1" MinInstancesInService: "1" RollingUpdateEnabled: "true" RollingUpdateType: "Health" "aws:autoscaling:trigger": - LowerThreshold: "10" + LowerThreshold: "30" MeasureName: "CPUUtilization" + Statistic: "Maximum" Unit: "Percent" - UpperThreshold: "200" - "aws:rds:dbinstance": - DBDeletionPolicy: "Snapshot" - DBAllocatedStorage: "10" - DBEngine: "postgres" - DBEngineVersion: "12.3" - DBInstanceClass: "db.t2.small" + UpperThreshold: "60" "aws:elasticbeanstalk:environment": LoadBalancerType: "application" + "aws:elasticbeanstalk:environment:process:default": + MatcherHTTPCode: 301 "aws:elasticbeanstalk:command": BatchSize: "30" "aws:ec2:instances": InstanceTypes: "t2.small" + "aws:elasticbeanstalk:cloudwatch:logs": + StreamLogs: true + DeleteOnTerminate: false + RetentionInDays: 7 diff --git a/deployments/staging/00_options.config b/deployments/staging/00_options.config new file mode 100644 index 0000000000..60bd027019 --- /dev/null +++ b/deployments/staging/00_options.config @@ -0,0 +1,32 @@ +option_settings: + "aws:autoscaling:launchconfiguration": + IamInstanceProfile : "aws-elasticbeanstalk-ec2-role" + EC2KeyName : "aws-eb" + RootVolumeSize : "100" + RootVolumeType : "gp2" + "aws:autoscaling:asg": + MinSize: 1 + MaxSize: 2 + "aws:autoscaling:updatepolicy:rollingupdate": + MaxBatchSize: "1" + MinInstancesInService: "1" + RollingUpdateEnabled: "true" + RollingUpdateType: "Health" + "aws:autoscaling:trigger": + LowerThreshold: "30" + MeasureName: "CPUUtilization" + Statistic: "Maximum" + Unit: "Percent" + UpperThreshold: "60" + "aws:elasticbeanstalk:environment": + LoadBalancerType: "application" + "aws:elasticbeanstalk:environment:process:default": + MatcherHTTPCode: 301 + "aws:elasticbeanstalk:command": + BatchSize: "30" + "aws:ec2:instances": + InstanceTypes: "t2.micro" + "aws:elasticbeanstalk:cloudwatch:logs": + StreamLogs: true + DeleteOnTerminate: true + RetentionInDays: 3