diff --git a/ansible/playbooks/deploy_app.yml b/ansible/playbooks/deploy_app.yml index ef7d6ccd7..095fc440e 100644 --- a/ansible/playbooks/deploy_app.yml +++ b/ansible/playbooks/deploy_app.yml @@ -114,33 +114,41 @@ git: repo: https://github.com/samuelclay/NewsBlur.git dest: /srv/newsblur/ - version: master + version: blue-green-deploy register: pulled tags: - static - name: Run new Docker container with temporary name docker_container: - name: "newsblur_web_new" - image: "newsblur/newsblur_web:latest" - pull: true + name: newsblur_web_new + image: newsblur/newsblur_python3 + container_default_behavior: no_defaults + pull: yes + env: + DOCKERBUILD: "" state: started - restart_policy: always - command: "gunicorn newsblur.wsgi:application --bind :8000 --workers 4" - hostname: "newsblur_web_new" + command: gunicorn --config /srv/newsblur/config/gunicorn_conf.py newsblur_web.wsgi:application + env: + TEMP8001: "true" + hostname: "{{ inventory_hostname }}" + log_driver: json-file + log_options: + max-size: 100m + networks_cli_compatible: yes + network_mode: default networks: - - name: newsblur-network + - name: newsblurnet ports: - - "8001:8000" # Use different port for new instance + - "8001:8000" + restart_policy: unless-stopped + user: 1000:1001 volumes: - /srv/newsblur:/srv/newsblur - - /etc/nginx/sites-enabled:/etc/nginx/sites-enabled - - /etc/nginx/sites-available:/etc/nginx/sites-available - - /srv/secrets-newsblur:/srv/secrets-newsblur - name: Wait for new temp container to be healthy uri: - url: "http://localhost:8001/api/health-check" # Add health check endpoint + url: "http://localhost:8001/health-check" status_code: 200 validate_certs: no register: result @@ -150,26 +158,34 @@ - name: Run new Docker container with original name docker_container: - name: "newsblur_web" - image: "newsblur/newsblur_web:latest" - pull: true + name: newsblur_web + image: newsblur/newsblur_python3 + container_default_behavior: no_defaults + pull: yes + env: + DOCKERBUILD: "" state: started - restart_policy: always - command: "gunicorn newsblur.wsgi:application --bind :8000 --workers 4" - hostname: "newsblur_web" + command: gunicorn --config /srv/newsblur/config/gunicorn_conf.py newsblur_web.wsgi:application + env: + TEMP8001: "true" + hostname: "{{ inventory_hostname }}" + log_driver: json-file + log_options: + max-size: 100m + networks_cli_compatible: yes + network_mode: default networks: - - name: newsblur-network + - name: newsblurnet ports: - "8000:8000" + restart_policy: unless-stopped + user: 1000:1001 volumes: - /srv/newsblur:/srv/newsblur - - /etc/nginx/sites-enabled:/etc/nginx/sites-enabled - - /etc/nginx/sites-available:/etc/nginx/sites-available - - /srv/secrets-newsblur:/srv/secrets-newsblur - + - name: Wait for new original container to be healthy uri: - url: "http://localhost:8000/api/health-check" + url: "http://localhost:8000/health-check" status_code: 200 validate_certs: no register: result diff --git a/apps/static/views.py b/apps/static/views.py index 9b2f04df4..3f5e46e4b 100644 --- a/apps/static/views.py +++ b/apps/static/views.py @@ -131,3 +131,7 @@ def redis_check(request): if key: return HttpResponse(unicode(key)) assert False, "Cannot read from redis-%s database" % pool + + +def health_check(request): + return HttpResponse("OK") diff --git a/config/gunicorn_conf.py b/config/gunicorn_conf.py index 4afef20f4..62fff7529 100644 --- a/config/gunicorn_conf.py +++ b/config/gunicorn_conf.py @@ -12,6 +12,9 @@ GIGS_OF_MEMORY = psutil.virtual_memory().total / 1024 / 1024 / 1024.0 NUM_CPUS = psutil.cpu_count() bind = "0.0.0.0:8000" +if os.environ.get("TEMP8001", False): + bind = "0.0.0.0:8001" + pidfile = "/srv/newsblur/logs/gunicorn.pid" logfile = "/srv/newsblur/logs/production.log" accesslog = "/srv/newsblur/logs/production.log" @@ -25,6 +28,7 @@ forwarded_allow_ips = "*" limit_request_line = 16000 limit_request_fields = 1000 worker_tmp_dir = "/dev/shm" +reload = False workers = max(int(math.floor(GIGS_OF_MEMORY * 2)), 3) @@ -33,6 +37,7 @@ if workers > 16: if os.environ.get("DOCKERBUILD", False): workers = 2 + reload = True # If hostname has staging in it, only 2 workers if app_env and "staging" in getattr(app_env, "SERVER_NAME", ""): diff --git a/newsblur_web/entrypoint.sh b/newsblur_web/entrypoint.sh index ec6d252df..732f43dec 100755 --- a/newsblur_web/entrypoint.sh +++ b/newsblur_web/entrypoint.sh @@ -2,5 +2,5 @@ if [[ -z "${TEST}" && "${TEST}" = "True" ]] then echo " ---> Starting test env" -else python3 manage.py check_db; gunicorn -c config/gunicorn_conf.py --reload newsblur_web.wsgi:application +else python3 manage.py check_db; gunicorn -c config/gunicorn_conf.py newsblur_web.wsgi:application fi diff --git a/newsblur_web/urls.py b/newsblur_web/urls.py index 309ad76fe..e1a05938c 100644 --- a/newsblur_web/urls.py +++ b/newsblur_web/urls.py @@ -84,6 +84,7 @@ urlpatterns = [ url(r"^account/ifttt/v1/", include("apps.oauth.urls")), url(r"^account/", include("oauth2_provider.urls", namespace="oauth2_provider")), url(r"^monitor/", include("apps.monitor.urls"), name="monitor"), + url(r"^health-check/", static_views.health_check, name="health-check"), url("", include("django_prometheus.urls")), ]