diff --git a/.github/workflows/deploy-pr.yml b/.github/workflows/deploy-pr.yml new file mode 100644 index 0000000..2e0bd63 --- /dev/null +++ b/.github/workflows/deploy-pr.yml @@ -0,0 +1,92 @@ +name: Deploy PR to Remote Server + +on: + workflow_dispatch: + inputs: + pr_number: + description: 'PR number to deploy' + required: true + type: number + +concurrency: + group: deploy-pr-${{ inputs.pr_number }} + cancel-in-progress: true + +env: + REGISTRY: ghcr.io + APP_IMAGE_NAME: ${{ github.repository }} + NGINX_IMAGE_NAME: ${{ github.repository }}-nginx + +jobs: + deploy: + runs-on: ubuntu-latest + environment: deploy-web + permissions: + pull-requests: write + + steps: + - name: Get PR details + id: pr + uses: actions/github-script@v7 + with: + script: | + const prNumber = ${{ inputs.pr_number }}; + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + core.setOutput('head_ref', pr.head.ref); + core.setOutput('pr_number', prNumber); + + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts + + - name: Deploy to remote server + id: deploy + run: | + OUTPUT=$(ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT || 22 }} ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} ${{ inputs.pr_number }}) + echo "$OUTPUT" + DEPLOY_URL=$(echo "$OUTPUT" | tail -n 1) + echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT + + - name: Cleanup SSH + if: always() + run: | + rm -f ~/.ssh/deploy_key + + - name: Comment deployment and documentation links + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ steps.pr.outputs.pr_number }} + header: deployment + message: | + 🚀 **PR deployed successfully!** + + **Website:** ${{ steps.deploy.outputs.url }} + + **Documentation:** https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.pr.outputs.head_ref }}/ + + **Docker Images:** + - App: `${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:pr-${{ steps.pr.outputs.pr_number }}` + - Nginx: `${{ env.REGISTRY }}/${{ env.NGINX_IMAGE_NAME }}:pr-${{ steps.pr.outputs.pr_number }}` + + - name: Remove awaiting-deployment label + if: always() + uses: actions/github-script@v7 + with: + script: | + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ steps.pr.outputs.pr_number }}, + name: 'awaiting-deployment' + }); + } catch (error) { + console.log('Label may have already been removed'); + } diff --git a/deploy/complete/docker-compose.yaml b/deploy/complete/docker-compose.yaml new file mode 100644 index 0000000..04b9e8a --- /dev/null +++ b/deploy/complete/docker-compose.yaml @@ -0,0 +1,62 @@ +x-kompass: + &kompass + image: ghcr.io/chrisflav/kompass:latest + env_file: docker.env + environment: + - DJANGO_SETTINGS_MODULE=jdav_web.settings + - KOMPASS_CONFIG_DIR_PATH=/app/config/ + restart: always + depends_on: + - db + - redis + - cache + +services: + master: + <<: *kompass + entrypoint: /app/docker/production/entrypoint-master.sh + volumes: + - uwsgi_data:/tmp/uwsgi/ + - web_static:/app/static/ + - web_static:/var/www/jdav_web/static/ + - ./config:/app/config:ro + + nginx: + image: ghcr.io/chrisflav/kompass-nginx:latest + restart: always + volumes: + - uwsgi_data:/tmp/uwsgi/ + - web_static:/var/www/jdav_web/static/:ro + ports: + - "3000:80" + depends_on: + - master + + db: + restart: always + image: mariadb:latest + env_file: docker.env + + cache: + restart: always + image: memcached:alpine + + redis: + restart: always + image: redis:6-alpine + + celery_worker: + <<: *kompass + entrypoint: /app/docker/production/entrypoint-celery-worker.sh + volumes: + - ./config:/app/config:ro + + celery_beat: + <<: *kompass + entrypoint: /app/docker/production/entrypoint-celery-beat.sh + volumes: + - ./config:/app/config:ro + +volumes: + uwsgi_data: + web_static: diff --git a/jdav_web/jdav_web/settings/components/base.py b/jdav_web/jdav_web/settings/components/base.py index b7e8f1a..c8c4aa3 100644 --- a/jdav_web/jdav_web/settings/components/base.py +++ b/jdav_web/jdav_web/settings/components/base.py @@ -142,7 +142,7 @@ DEFAULT_STATIC_PATH = get_var("django", "default_static_path", default="/app/jda LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),) # Celery and Redis setup -BROKER_URL = get_var("django", "broker_url", default="redis://localhost:6379/0") +BROKER_URL = get_var("django", "broker_url", default="redis://redis:6379/0") # password hash algorithms used diff --git a/jdav_web/jdav_web/settings/components/cache.py b/jdav_web/jdav_web/settings/components/cache.py index 55ff0a4..e974a42 100644 --- a/jdav_web/jdav_web/settings/components/cache.py +++ b/jdav_web/jdav_web/settings/components/cache.py @@ -3,7 +3,7 @@ CACHES = { "default": { "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", - "LOCATION": get_var("django", "memcached_url", default="127.0.0.1:11211"), + "LOCATION": get_var("django", "memcached_url", default="cache:11211"), "OPTIONS": { "no_delay": True, "ignore_exc": True, diff --git a/jdav_web/jdav_web/settings/components/database.py b/jdav_web/jdav_web/settings/components/database.py index 11171af..46ee370 100644 --- a/jdav_web/jdav_web/settings/components/database.py +++ b/jdav_web/jdav_web/settings/components/database.py @@ -6,10 +6,10 @@ DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", - "NAME": get_var("database", "database", default="jdav_db"), - "USER": get_var("database", "user", default="user"), + "NAME": get_var("database", "database", default="kompass"), + "USER": get_var("database", "user", default="kompass"), "PASSWORD": get_var("database", "password", default="secret"), - "HOST": get_var("database", "host", default="127.0.0.1"), - "PORT": get_var("database", "port", default=5432), + "HOST": get_var("database", "host", default="db"), + "PORT": get_var("database", "port", default=3306), } }