Web Server Setup¶
This guide covers setting up the web server layer including Nginx configuration, SSL certificates, and UI deployment.
Prerequisites
Before starting, ensure you have completed the Installation steps.
1. Nginx Configuration¶
Configure Nginx to serve both the UI and API:
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/run/gunicorn.socket fail_timeout=0;
}
server {
listen 443 ssl;
server_name your-labid.com;
root /opt/labid-ui/dist; # UI static files
index index.html;
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
# API requests go to Django
location ~ ^/(admin|api|api-auth|metrics) {
proxy_pass http://app_server;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Static files from Django
location ^~ /static/ {
alias /opt/labid/labid/static_collection/;
}
location ^~ /attachments/ {
alias /opt/labid/labid/storage/attachments/;
}
# SPA routing for UI
location / {
try_files $uri $uri/ /index.html;
}
}
Configuration Examples¶
Example Nginx configurations are available in the repository:
- deploy/nginx/labid.conf - Production configuration
- deploy/nginx/docker.conf - Docker-compose configuration
2. SSL Certificate Setup¶
Install SSL certificate using Let's Encrypt:
# Install certbot
sudo apt install certbot python3-certbot-nginx
# Obtain and install certificate
sudo certbot --nginx -d your-labid.com
# Verify automatic renewal
sudo certbot renew --dry-run
Manual Certificate Installation¶
If using a custom certificate:
# Copy certificate files
sudo cp your-certificate.crt /etc/ssl/certs/labid.crt
sudo cp your-private-key.key /etc/ssl/private/labid.key
# Set appropriate permissions
sudo chmod 644 /etc/ssl/certs/labid.crt
sudo chmod 600 /etc/ssl/private/labid.key
3. UI Deployment¶
The LabID UI is a Vue.js single-page application (SPA). It is compiled into static files that Nginx serves directly — there is no running Node.js process in production.
Step 1 — Install Node.js via nvm¶
nvm (Node Version Manager) lets you install and switch Node versions without sudo or system-package conflicts.
# Install nvm (run as the labid user or your own user)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Restart your shell or source the init file, then:
nvm install --lts
nvm use --lts
Step 2 — Clone the repository and install dependencies¶
cd /opt
sudo git clone https://gitlab.com/lab-integrated-data/labid-ui.git labid-ui
sudo chown -R labid:labid labid-ui
sudo -u labid -i
cd /opt/labid-ui
git checkout production
npm install
# Do NOT run npm run build yet — configure the environment first (Step 3)
Step 3 — Configure .env.local before building¶
Environment variables are baked in at compile time
The UI is a compiled SPA. Values in .env.local are embedded into the JavaScript bundle during npm run build. If you build before setting the correct URL, the wrong URL is hard-coded into production — changing .env.local afterwards has no effect until you rebuild.
Update the following variables in .env:
# Full public API URL — must include /api/v2
VITE_API_URL=https://your-labid.com/api/v2
# Public base URL of your LabID instance
VITE_DEPLOYMENT_URL=https://your-labid.com
Use https:// — not http:// and not the internal hostname
If your site is served over TLS (https://) but VITE_API_URL contains an http:// URL or refers to an internal hostname and port (e.g. http://bs-myserver.ethz.ch:8000), browsers will block the API calls as mixed active content. The result is the "Server is down" banner on the home page, even though the backend itself is running fine.
Always set VITE_API_URL to the public https:// domain that users access — not the internal gunicorn address.
For the full list of available options, see the UI repository .env file.
Step 4 — Build the UI¶
npm run build
# Outputs static files to /opt/labid-ui/dist/
# Nginx serves this directory directly (see Section 1 above)
npm run dev and npm run preview are development-only tools
npm run dev (port 5173) and npm run preview (port 4173) start temporary development servers. They are not a production deployment method — do not proxy Nginx to either of these ports. Production always uses the static files in dist/ served directly by Nginx.
Reference: The docker-compose configuration shows the complete integration between UI (Vue.js), backend (Django), and nginx routing.
4. LibreOffice Online (Optional)¶
For document editing capabilities, set up LibreOffice Online:
# Using Docker (recommended)
docker run -t -d -p 9980:9980 \
-e "extra_params=--o:ssl.enable=false" \
-e "username=admin" \
-e "password=secure_password" \
-e "domain=your-labid\\.com" \
--name=lool \
collabora/code
Configure LibreOffice Integration¶
Update your environment configuration:
# Add to /opt/labid/labid/.env
echo "DJANGO_LOOL_INSTANCE=http://localhost:9980" >> /opt/labid/labid/.env
echo "DJANGO_LOOL_WOPI_ADDRESS=https://your-labid.com" >> /opt/labid/labid/.env
Nginx Configuration for LibreOffice¶
Add LibreOffice routes to your Nginx configuration. See the docker-compose/web/default.conf for routing examples.
5. Testing Web Server Setup¶
Test Nginx Configuration¶
# Test Nginx configuration syntax
sudo nginx -t
# Reload Nginx if configuration is valid
sudo systemctl reload nginx
Verify Web Access¶
- Backend API:
https://your-labid.com/api/v2/version/ - Admin Interface:
https://your-labid.com/admin/ - UI Application:
https://your-labid.com/
Check SSL Certificate¶
6. Security Hardening¶
Nginx Security Headers¶
Add security headers to your Nginx configuration:
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "default-src 'self'";
Firewall Configuration¶
# Allow only necessary ports
sudo ufw allow 22 # SSH
sudo ufw allow 80 # HTTP
sudo ufw allow 443 # HTTPS
sudo ufw enable
Next Steps¶
- Complete Post-Installation Configuration
- Set up Maintenance procedures
- Review Troubleshooting guide