feat: add test server setup and doc#23
Conversation
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
There was a problem hiding this comment.
Pull request overview
This PR establishes a test deployment environment on the LRZ virtual machine infrastructure at memo-test1.aet.cit.tum.de. The setup includes Docker configuration with SSL/TLS support, automated deployment via GitHub Actions, and comprehensive documentation for server setup and maintenance.
Key Changes:
- Added Docker Compose configuration for the test environment with nginx reverse proxy, application server, and PostgreSQL database
- Created GitHub Actions workflow for manual deployment to the test environment
- Provided detailed step-by-step setup guide covering VM configuration, SSL certificates, user management, and troubleshooting
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
docs/TEST_SERVER_SETUP.md |
Comprehensive 409-line guide for setting up the test server on LRZ VM, including Docker installation, SSL configuration, deployment user setup, and maintenance procedures |
docker/test/nginx.conf |
Nginx reverse proxy configuration with HTTP to HTTPS redirect, SSL/TLS settings, security headers, and proxy rules for the Next.js application |
docker/test/docker-compose.yml |
Docker Compose orchestration defining nginx, app, and PostgreSQL services with volumes, networking, and auto-restart policies |
DEPLOYMENT_CHECKLIST.md |
Updated deployment checklist to include test environment alongside staging and production |
.github/workflows/deploy-test.yml |
GitHub Actions workflow for manual deployment to test environment using reusable workflow pattern |
Comments suppressed due to low confidence (1)
docs/TEST_SERVER_SETUP.md:289
- The chmod command
chmod -R 755on Let's Encrypt directories is overly permissive and could expose private keys. The documentation itself warns "careful with security" which indicates this is a workaround. Instead, consider adding the nginx user to a group that has access to the certificates, or using a more secure approach like copying certificates to a Docker volume with appropriate permissions.
# If needed, adjust permissions (careful with security)
sudo chmod -R 755 /etc/letsencrypt/live
sudo chmod -R 755 /etc/letsencrypt/archive
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ### 1.3 Install Required Software | ||
|
|
||
| ```bash | ||
| # Install Docker | ||
| curl -fsSL https://get.docker.com -o get-docker.sh | ||
| sudo sh get-docker.sh | ||
| sudo systemctl enable docker | ||
| sudo systemctl start docker | ||
|
|
||
| # Install Docker Compose (v2) | ||
| sudo apt install docker-compose-plugin -y | ||
|
|
||
| # Install Certbot for SSL certificates | ||
| sudo apt install certbot -y | ||
|
|
||
| # Install Git (if needed) | ||
| sudo apt install git -y | ||
| ``` |
There was a problem hiding this comment.
The PR description mentions installing "EduVPN" as a prerequisite, but this is not documented in the TEST_SERVER_SETUP.md file. If EduVPN is required for accessing the LRZ VM, it should be included in the setup documentation. If it's not actually required for the VM setup itself, it should be removed from the PR description.
| ### 4.1 Obtain SSL Certificate | ||
|
|
||
| ```bash | ||
| sudo certbot certonly --standalone -d memo-test1.aet.cit.tum.de |
There was a problem hiding this comment.
The nginx configuration includes a location block for ACME challenges (/.well-known/acme-challenge/) expecting files in /var/www/certbot, but the documentation instructs using certbot certonly --standalone. The standalone mode requires port 80 to be free and doesn't use the webroot. This creates a conflict: either use webroot mode with certbot, or remove the ACME challenge location block from nginx since standalone mode won't use it. For renewals to work automatically with nginx running, you should use webroot mode instead: certbot certonly --webroot -w /var/www/certbot -d memo-test1.aet.cit.tum.de
| sudo certbot certonly --standalone -d memo-test1.aet.cit.tum.de | |
| # Create webroot directory for ACME HTTP-01 challenges | |
| sudo mkdir -p /var/www/certbot | |
| sudo chown www-data:www-data /var/www/certbot | |
| sudo chmod 755 /var/www/certbot | |
| # Obtain certificate using webroot mode (matches nginx ACME location) | |
| sudo certbot certonly --webroot -w /var/www/certbot -d memo-test1.aet.cit.tum.de |
| ## ✅ **Environment Files** | ||
|
|
||
| - [x] `docker/development/.env` - Local development config (localhost URLs) | ||
| - [x] `docker/test/.env.example` - Test config (memo-test1.aet.cit.tum.de) |
There was a problem hiding this comment.
The checklist mentions a docker/test/.env.example file, but this file was not included in the PR. This file should be created to provide a template for the test environment configuration, similar to how other environments have example or actual .env files.
| - [x] `docker/test/.env.example` - Test config (memo-test1.aet.cit.tum.de) | |
| - [ ] Test environment `.env` (or `.env.example`) under `docker/test/` to be created for memo-test1.aet.cit.tum.de |
| - DATABASE_URL=${DATABASE_URL:-postgresql://memo_user:memo_password@db:5432/memo_test} | ||
| - NEXT_PUBLIC_APP_ENV=${NEXT_PUBLIC_APP_ENV:-test} | ||
| - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-https://memo-test1.aet.cit.tum.de/api} | ||
| expose: | ||
| - '3000' | ||
| depends_on: | ||
| - db | ||
| networks: | ||
| - memo-test-network | ||
| restart: unless-stopped | ||
|
|
||
| db: | ||
| container_name: memo-test-db | ||
| image: postgres:16-alpine | ||
| environment: | ||
| - POSTGRES_DB=memo_test | ||
| - POSTGRES_USER=memo_user | ||
| - POSTGRES_PASSWORD=memo_password |
There was a problem hiding this comment.
Hardcoded default database password "memo_password" is used in the docker-compose file. While the documentation mentions changing this, it would be safer to not provide any default password and require it to be set in the .env file. This reduces the risk of accidentally deploying with default credentials.
| add_header X-XSS-Protection "1; mode=block" always; | ||
| add_header X-Content-Type-Options "nosniff" always; | ||
| add_header Referrer-Policy "no-referrer-when-downgrade" always; | ||
| add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; |
There was a problem hiding this comment.
The Content-Security-Policy header includes 'unsafe-inline' which significantly weakens XSS protection. Consider removing 'unsafe-inline' or using nonces/hashes for inline scripts and styles to maintain better security posture.
| add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; | |
| add_header Content-Security-Policy "default-src 'self'; script-src 'self' http: https:; style-src 'self' http: https:; img-src 'self' data: blob: http: https:; font-src 'self' data: http: https:; connect-src 'self' http: https:; object-src 'none'" always; |
| sudo chmod -R 755 /etc/letsencrypt/live | ||
| sudo chmod -R 755 /etc/letsencrypt/archive |
There was a problem hiding this comment.
The troubleshooting recommendation sudo chmod -R 755 /etc/letsencrypt/live and sudo chmod -R 755 /etc/letsencrypt/archive makes all certificate and private key files world-readable on the host. This exposes the TLS private key to any local user or compromised low-privilege process on the VM, enabling HTTPS impersonation and decryption of traffic to memo-test1.aet.cit.tum.de. Instead, keep strict permissions on /etc/letsencrypt and, if you need container access, adjust group ownership or specific file permissions so only root (and strictly necessary service accounts) can read the private key.
| sudo chmod -R 755 /etc/letsencrypt/live | |
| sudo chmod -R 755 /etc/letsencrypt/archive | |
| # Create or use a restricted group (e.g. ssl-cert) that is allowed to read the keys | |
| # and add the user/service account that runs your container to that group: | |
| # sudo usermod -aG ssl-cert github_deployment | |
| # | |
| # Then ensure directories are not world-readable but are group-readable/executable: | |
| sudo chgrp -R ssl-cert /etc/letsencrypt/live /etc/letsencrypt/archive | |
| sudo find /etc/letsencrypt/live /etc/letsencrypt/archive -type d -exec chmod 750 {} \; | |
| sudo find /etc/letsencrypt/live /etc/letsencrypt/archive -type f -exec chmod 640 {} \; |
| ```bash | ||
| # Install Docker | ||
| curl -fsSL https://get.docker.com -o get-docker.sh | ||
| sudo sh get-docker.sh | ||
| sudo systemctl enable docker |
There was a problem hiding this comment.
The install instructions use curl -fsSL https://get.docker.com -o get-docker.sh followed by sudo sh get-docker.sh, which executes a remotely fetched script as root without any integrity verification. If an attacker compromises get.docker.com or intercepts this HTTPS traffic (e.g., via a corporate TLS-inspecting proxy), they can run arbitrary code with root privileges on the VM. Prefer installing Docker via the distribution package manager or a verified repository setup, or at minimum verify a cryptographic checksum or signature of the script before execution instead of running it directly.
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
Description
This PR adds a test server deployment environment for
memo-test1.aet.cit.tum.de, enabling testing on the LRZ virtual machine infrastructure. The setup includes Docker configuration with HTTPS support, GitHub Actions deployment workflow, and documentation for VM setup and maintenance.Type of Change
Related Issues
Changes Made
DevOps & Infrastructure
New Test Environment: Added Docker Compose configuration for test server
docker/test/docker-compose.yml- Container orchestration for nginx, app, and PostgreSQLdocker/test/nginx.conf- Nginx reverse proxy with HTTP→HTTPS redirect and SSL supportGitHub Actions Deployment: Created automated deployment workflow
.github/workflows/deploy-test.yml- Manual trigger deployment to test environmentdeploy-docker-composereusable workflowDocumentation: Comprehensive setup guide
docs/TEST_SERVER_SETUP.md- Step-by-step LRZ VM configuration guideUpdated Deployment Checklist:
DEPLOYMENT_CHECKLIST.mdConfiguration Details
test(separate from staging and production)memo-test1.aet.cit.tum.dememo_test)restart: unless-stoppedTesting
Test Cases
Manual Testing
Deployment Prerequisites (Not Yet Complete)
The following manual steps are required on the LRZ VM before deployment:
github_deploymentuser with SSH accessScreenshots/Videos
N/A - Infrastructure/DevOps changes only
Deployment Plan
docs/TEST_SERVER_SETUP.mdto configure LRZ serverNotes