diff --git a/.circleci/config.yml b/.circleci/config.yml index 88fb807a..6ff07610 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 jobs: run_tests: docker: - - image: node:18-bookworm + - image: node:22-bookworm - image: postgres environment: POSTGRES_DB: "zosia" @@ -35,35 +35,17 @@ jobs: deploy: docker: - - image: node:18-bookworm + - image: cimg/gcp:2024.08 steps: - - run: - name: Install gcloud and python-pip - command: | - DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y curl apt-transport-https ca-certificates gnupg - echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - - apt-get update - - DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y python3-pip python3-dev google-cloud-sdk - echo ${GCLOUD_KEY} | base64 --decode | gcloud auth activate-service-account --key-file=- - gcloud --quiet config set project ${GCLOUD_PROJECT} - gcloud --quiet config set compute/zone europe_central2 - checkout + - setup_remote_docker - run: - name: Build frontend + name: Run deploy.sh script command: | - (cd ./app && npm install) - - run: - name: Collect static files - # we could prepare separate setting files for this without dependencies and with different STATIC_ROOT - command: | - python3 -m pip install --break-system-packages -r ./app/requirements.txt - cd ./app/server && python3 ../manage.py collectstatic --no-input && cp -r /static/. ../static/ && python3 ../manage.py generate_client_assets + echo ${GCP_PROJECT_KEY_BASE64_ENCODED} | base64 --decode --ignore-garbage > $HOME/gcloud-service-key.json + gcloud auth activate-service-account --key-file=$HOME/gcloud-service-key.json - - run: - name: Push image to App Engine - command: (cd ./app && gcloud app deploy app.yaml) + cd ./app && ./deploy.sh ${GCP_PROJECT_ID} # - run: # name: Purge cache # command: | @@ -83,5 +65,4 @@ workflows: filters: branches: only: - # - master - - zosia_2025 + - master diff --git a/app/Dockerfile b/app/Dockerfile index 8f0faf6e..efa4331f 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -1,4 +1,4 @@ -FROM nikolaik/python-nodejs:python3.10-nodejs18-alpine AS base +FROM nikolaik/python-nodejs:python3.12-nodejs22-alpine AS base # Env variables ENV PYTHONUNBUFFERED=1 @@ -58,3 +58,5 @@ COPY scripts ./scripts # Build frontend RUN python manage.py generate_client_assets RUN python manage.py build + +ENTRYPOINT [ "./scripts/start_prod_server.sh" ] diff --git a/app/deploy.sh b/app/deploy.sh index 2c6a9540..7cf4d6a7 100755 --- a/app/deploy.sh +++ b/app/deploy.sh @@ -1,28 +1,39 @@ #!/bin/sh set -eu -PROJECT_ID="" +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +PROJECT_ID="$1" REPO_NAME=zosia-repo -REGION=europe-central2 +REGION=europe-west4 REPO_HOSTNAME=$REGION-docker.pkg.dev IMAGE_NAME=zosia_prod IMAGE_URL=$REPO_HOSTNAME/$PROJECT_ID/$REPO_NAME/$IMAGE_NAME:latest -# Configure gcloud and docker to be able to push to the Google Container Registry +echo "[1] Configuring gcloud and docker to be able to push to the Google Container Registry" gcloud config set project $PROJECT_ID +gcloud config set compute/zone $REGION gcloud auth configure-docker $REPO_HOSTNAME -# Build and push the image +echo "[2] Building and pushing the image" docker build --target prod -t $IMAGE_URL . docker push $IMAGE_URL -# Run the migration job +echo "[3] Running migrations" +gcloud run jobs update migrate --region=$REGION --image $IMAGE_URL gcloud run jobs execute migrate --wait --region=$REGION -# Run the collectstatic job which will collect all the static files into GCS bucket +echo "[4] Collecting static files into a GCS bucket" +gcloud run jobs update collectstatic --region=$REGION --image $IMAGE_URL gcloud run jobs execute collectstatic --wait --region=$REGION -# Deploy new service revision with the new image +echo "[5] Updating createsuperuser job to use the new image" +gcloud run jobs update createsuperuser --region=$REGION --image $IMAGE_URL + +echo "[6] Deploying the new image" gcloud run services update zosia --region $REGION --image $IMAGE_URL diff --git a/app/scripts/createsuperuser.sh b/app/scripts/createsuperuser.sh new file mode 100755 index 00000000..6f527fa4 --- /dev/null +++ b/app/scripts/createsuperuser.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -eu + +# This script creates a superuser based on the environment variables: +# DJANGO_SUPERUSER_USERNAME +# DJANGO_SUPERUSER_EMAIL +# DJANGO_SUPERUSER_PASSWORD + +python manage.py createsuperuser --noinput \ No newline at end of file diff --git a/app/server/settings/common.py b/app/server/settings/common.py index 2e520a90..a887af48 100644 --- a/app/server/settings/common.py +++ b/app/server/settings/common.py @@ -65,6 +65,7 @@ def random_string(length=10): DEBUG = False ALLOWED_HOSTS = os.environ.get("HOSTS", "staging.zosia.org").split(",") +CSRF_TRUSTED_ORIGINS = [f"https://*.{host}" for host in ALLOWED_HOSTS] AUTH_USER_MODEL = "users.User" diff --git a/app/server/settings/dev.py b/app/server/settings/dev.py index 9c340e83..22b03310 100644 --- a/app/server/settings/dev.py +++ b/app/server/settings/dev.py @@ -54,3 +54,4 @@ # Especially room.js makes heavy use of it INTERNAL_IPS = ['127.0.0.1'] ALLOWED_HOSTS = ['127.0.0.1', '0.0.0.0', 'localhost'] +CSRF_TRUSTED_ORIGINS = [f"http://*.{host}" for host in ALLOWED_HOSTS]