docs: add ci cd and deployment runbook to handbook
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
<a href="#builders">Builders</a>
|
||||
<a href="#testing">Testing</a>
|
||||
<a href="#backup">Backup</a>
|
||||
<a href="#cicd">CI/CD</a>
|
||||
<a href="#deploy">Deployment</a>
|
||||
<a href="#troubleshooting">Troubleshooting</a>
|
||||
<a href="#security">Security</a>
|
||||
@@ -266,7 +267,95 @@ make backup-verify BACKUP_DIR=backups/backup_YYYYmmdd_HHMMSS</code></pre>
|
||||
<li>The staff UI uses the shared action-progress overlay for backup creation and verification so long-running actions present one standard app behavior.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="deploy">13) Deployment and Release Checklist</h2>
|
||||
<h2 id="cicd">13) CI/CD</h2>
|
||||
<ul>
|
||||
<li>Repository model: one private GitHub repository, not separate dev/prod repositories.</li>
|
||||
<li>Branch model: <code>develop</code> for the test deployment, <code>main</code> reserved for production.</li>
|
||||
<li>Current test workflow file: <code>.github/workflows/deploy-test.yml</code>.</li>
|
||||
<li>Current production workflow file: <code>.github/workflows/deploy-prod.yml</code>.</li>
|
||||
<li>GitHub Actions uploads the working tree to the server over SSH. The server does not clone from GitHub.</li>
|
||||
<li>This is intentional for a private repository: it removes the need to store GitHub deploy keys on the target server.</li>
|
||||
</ul>
|
||||
<h3>GitHub Environments</h3>
|
||||
<ul>
|
||||
<li>Create GitHub environments named <code>development</code> and <code>production</code>.</li>
|
||||
<li><strong>Development</strong> secrets:
|
||||
<ul>
|
||||
<li><code>TEST_DEPLOY_HOST</code></li>
|
||||
<li><code>TEST_DEPLOY_USER</code></li>
|
||||
<li><code>TEST_DEPLOY_PORT</code></li>
|
||||
<li><code>TEST_DEPLOY_PATH</code></li>
|
||||
<li><code>TEST_DEPLOY_SSH_KEY</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Production</strong> secrets:
|
||||
<ul>
|
||||
<li><code>PROD_DEPLOY_HOST</code></li>
|
||||
<li><code>PROD_DEPLOY_USER</code></li>
|
||||
<li><code>PROD_DEPLOY_PORT</code></li>
|
||||
<li><code>PROD_DEPLOY_PATH</code></li>
|
||||
<li><code>PROD_DEPLOY_SSH_KEY</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Current test deployment values</h3>
|
||||
<ul>
|
||||
<li>Host: <code>192.168.2.55</code></li>
|
||||
<li>User: <code>root</code></li>
|
||||
<li>Path: <code>/opt/workdock</code></li>
|
||||
<li>URL: <code>http://192.168.2.55:8088</code></li>
|
||||
</ul>
|
||||
<div class="note">
|
||||
The current LAN test deployment intentionally uses <code>DJANGO_DEBUG=1</code> in <code>.env.test</code> because the security checks correctly reject insecure cookie settings when <code>DEBUG=0</code> and the deployment is still plain HTTP. This is acceptable for the internal test box only. Production must run with HTTPS and <code>DEBUG=0</code>.
|
||||
</div>
|
||||
|
||||
<h2 id="deploy">14) Deployment</h2>
|
||||
<h3>Test server stack</h3>
|
||||
<ul>
|
||||
<li>Stack file: <code>docker-compose.prod.yml</code></li>
|
||||
<li>Entrypoints:
|
||||
<ul>
|
||||
<li><code>backend/entrypoint-web-prod.sh</code></li>
|
||||
<li><code>backend/entrypoint-worker-prod.sh</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Reverse proxy/static/media: <code>deploy/Caddyfile</code></li>
|
||||
<li>Main deploy script: <code>scripts/deploy_stack.sh</code></li>
|
||||
</ul>
|
||||
<h3>What the deploy script does</h3>
|
||||
<ol>
|
||||
<li>Validate env file presence</li>
|
||||
<li>Build <code>web</code>, <code>worker</code>, and <code>caddy</code></li>
|
||||
<li>Start <code>db</code> and <code>redis</code></li>
|
||||
<li>Initialize writable volume ownership for media/static/backups</li>
|
||||
<li>Run migrations</li>
|
||||
<li>Run <code>bootstrap_initial_users</code></li>
|
||||
<li>Run <code>collectstatic</code></li>
|
||||
<li>Optionally run <code>manage.py check</code></li>
|
||||
<li>Start <code>web</code>, <code>worker</code>, and <code>caddy</code></li>
|
||||
<li>Wait until <code>/healthz/</code> becomes healthy</li>
|
||||
</ol>
|
||||
<h3>Manual deploy</h3>
|
||||
<pre><code>cd /opt/workdock
|
||||
RUN_DJANGO_CHECK=0 DEPLOY_HEALTH_URL="http://127.0.0.1:8088/healthz/" ./scripts/deploy_stack.sh .env.test docker-compose.prod.yml</code></pre>
|
||||
<h3>Validation after deploy</h3>
|
||||
<pre><code>curl -I http://192.168.2.55:8088/healthz/
|
||||
ssh root@192.168.2.55 "cd /opt/workdock && docker compose --env-file .env.test -f docker-compose.prod.yml ps"</code></pre>
|
||||
<h3>Proxmox / LXC requirement</h3>
|
||||
<p>The current server is an Ubuntu CT on Proxmox running Docker inside the container. The CT required Proxmox-side configuration before Docker containers could start correctly.</p>
|
||||
<pre><code>features: nesting=1,keyctl=1
|
||||
lxc.apparmor.profile: unconfined
|
||||
lxc.mount.entry: /dev/null sys/module/apparmor/parameters/enabled none bind 0 0</code></pre>
|
||||
<p>Those lines belong in <code>/etc/pve/lxc/<CTID>.conf</code> on the Proxmox host, followed by <code>pct restart <CTID></code>.</p>
|
||||
<h3>Production expectations</h3>
|
||||
<ul>
|
||||
<li>Use a real hostname</li>
|
||||
<li>Use HTTPS</li>
|
||||
<li>Use <code>DJANGO_DEBUG=0</code></li>
|
||||
<li>Use secure cookies and SSL redirect</li>
|
||||
<li>Run deployment with <code>RUN_DJANGO_CHECK=1</code></li>
|
||||
</ul>
|
||||
<h3>Release checklist</h3>
|
||||
<ol>
|
||||
<li>Run <code>manage.py check</code></li>
|
||||
<li>Run tests or targeted verification</li>
|
||||
@@ -275,11 +364,11 @@ make backup-verify BACKUP_DIR=backups/backup_YYYYmmdd_HHMMSS</code></pre>
|
||||
<li>Generate at least one onboarding/offboarding PDF if PDF templates changed</li>
|
||||
<li>Verify MailHog or SMTP path if email behavior changed</li>
|
||||
<li>Verify Nextcloud upload if integration behavior changed</li>
|
||||
<li>Update Project Wiki and Developer Handbook if architecture/workflow changed</li>
|
||||
<li>Update Project Wiki and Developer Handbook if architecture or operational workflow changed</li>
|
||||
<li>Take a snapshot commit before major next-phase work</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="troubleshooting">14) Troubleshooting</h2>
|
||||
<h2 id="troubleshooting">15) Troubleshooting</h2>
|
||||
<ul>
|
||||
<li><strong>Page looks stale:</strong> restart <code>web</code> and hard-refresh browser</li>
|
||||
<li><strong>Second request hangs:</strong> inspect web logs and verify health endpoint</li>
|
||||
@@ -290,7 +379,7 @@ make backup-verify BACKUP_DIR=backups/backup_YYYYmmdd_HHMMSS</code></pre>
|
||||
<li><strong>Requests dependency warning appears:</strong> verify <code>chardet==5.2.0</code> is installed in the rebuilt image and restart <code>web</code>/<code>worker</code></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="security">15) Security and Maintenance Notes</h2>
|
||||
<h2 id="security">16) Security and Maintenance Notes</h2>
|
||||
<ul>
|
||||
<li>Containers run as non-root <code>app</code> user.</li>
|
||||
<li>Keep secrets in <code>.env</code>, not in tracked files.</li>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<li>{% trans "repository and service structure" %}</li>
|
||||
<li>{% trans "Docker and migration workflow" %}</li>
|
||||
<li>{% trans "translation and builder architecture" %}</li>
|
||||
<li>{% trans "deployment, security, and maintenance notes" %}</li>
|
||||
<li>{% trans "CI/CD, deployment, security, and maintenance notes" %}</li>
|
||||
</ul>
|
||||
<div class="actions">
|
||||
<a class="btn btn-secondary" href="/admin-tools/developer-handbook/">{% trans "Open Developer Handbook" %}</a>
|
||||
|
||||
Reference in New Issue
Block a user