Skip to content

[FEATURE] Add Docker Setup and Documentation#1023

Open
pulk17 wants to merge 11 commits into
CCExtractor:masterfrom
pulk17:feature/Docker
Open

[FEATURE] Add Docker Setup and Documentation#1023
pulk17 wants to merge 11 commits into
CCExtractor:masterfrom
pulk17:feature/Docker

Conversation

@pulk17
Copy link
Copy Markdown

@pulk17 pulk17 commented Feb 16, 2026

Please prefix your pull request with one of the following: [FEATURE] [FIX] [IMPROVEMENT].

In raising this pull request, I confirm the following (please check boxes):

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • I have considered, and confirmed that this submission will be valuable to others.
  • I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
  • I give this submission freely, and claim no ownership to its content.

My familiarity with the project is as follows (check one):

  • I have never used the project.
  • I have used the project briefly.
  • I have used the project extensively, but have not contributed previously.
  • I am an active contributor to the project.

This PR introduces a complete Docker-based development environment for the Sample Platform. It allows developers to spin up the entire application stack (Flask + MySQL) with a single command, eliminating manual dependency installation and configuration headaches.

Key Features

  • One-Command Setup: docker compose up --build handles everything from database creation to dependency installation.
  • Live Code Reloading: The local source code is mounted into the container, so changes are reflected immediately without rebuilding.
  • Automated Database Management:
    • Automatically waits for MySQL to be healthy.
    • Handles schema creation and migration stamping (flask db stamp head) on the first run.
    • Seeds the database with an admin user and sample data (configurable via .env).
  • Google Cloud Storage (GCS) Emulation:
    • Automatically generates a dummy service-account.json if one is missing, preventing startup crashes.
    • Supports mounting a real GCS bucket via gcsfuse if credentials are provided.
  • Security Best Practices:
    • SECRET_KEY and CSRF_SESSION_KEY are generated at runtime.
    • Runs with a non-root user (Gunicorn).

File Overview

  • Dockerfile: Multi-stage build based on Python 3.11-slim.
  • docker-compose.yml: Orchestrates the Flask backend and MySQL 8.0 database.
  • docker-entrypoint.sh: A robust startup script that handles:
    • Secret key generation.
    • Git repository initialization (required for build commit display).
    • Database waiting and migration strategies.
    • Gunicorn execution.
  • DOCKER.md: Comprehensive documentation on usage, architecture, and troubleshooting.
  • env.example: A template for environment variables tailored for Docker.
  • .dockerignore: Optimizes build context by excluding unnecessary files.

Design Decisions & Trade-offs

  • Runtime Secrets: We generate secrets in the entrypoint instead of the Dockerfile to prevent leaking them in image layers and to ensure every container has unique keys.
  • GCS Mounting: We mount GCS buckets to /mnt/gcs_repository instead of directly to /repository to avoid conflicts with Docker's volume mounting behavior.
  • Database Stamping: On a fresh DB, we use flask db stamp head because create_all() builds the schema faster than running 50+ migrations sequentially.

Documentation: See DOCKER.md for full details.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment thread mod_sample/controllers.py
}
raise SampleNotFoundException(f"Extra file {additional_id} for sample {sample.id} not found")
raise SampleNotFoundException(f"Sample with id {sample_id} not found")
raise SampleNotFoundException(f"Sample with id {sample_id} not found") No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this change please.

Comment thread .dockerignore
service-account.json
gcp-key.json
secret_key
secret_csrf No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a newline to the end.

Comment thread docker-compose.yml
@@ -0,0 +1,64 @@
services:
# --- 1. Database Service ---
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove all these unnecessary comments.

Comment thread docker-entrypoint.sh
Comment on lines +48 to +74
python3 -c "
import json
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

try:
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pem = key.private_bytes(serialization.Encoding.PEM,
serialization.PrivateFormat.TraditionalOpenSSL,
serialization.NoEncryption()).decode()
except Exception as e:
print(f'WARNING: Key generation failed: {e}')
pem = 'DUMMY_KEY'

sa = {
'type': 'service_account',
'project_id': 'docker-dev',
'private_key_id': 'docker-dev-key',
'private_key': pem,
'client_email': 'docker-dev@docker-dev.iam.gserviceaccount.com',
'client_id': '000000000000',
'auth_uri': 'https://accounts.google.com/o/oauth2/auth',
'token_uri': 'https://oauth2.googleapis.com/token',
}
with open('$REAL_SA_PATH', 'w') as f:
json.dump(sa, f, indent=2)
"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather see extra helper files (in the correct subfolder) than almost unreadable python in a shell script.

Comment thread docker-entrypoint.sh
@@ -0,0 +1,292 @@
#!/bin/bash
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is way too large for a entrypoint of a docker. A lot of these things should be handled at build time (ensuring dirs exist/created etc).

Comment thread Dockerfile
@@ -0,0 +1,81 @@
FROM python:3.11-slim-bullseye
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather see a more recent python version.

Comment thread env.example
# ============================================================

# ---------- MySQL ----------
MYSQL_ROOT_PASSWORD=root
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SP does not need to know the root password for MYSQL

Comment thread env.example
# Port exposed on the HOST for the Flask app (container always listens on 5000)
APP_PORT=5000
# Port exposed on the HOST for direct MySQL access (optional, for debugging)
DB_EXTERNAL_PORT=3306
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be exposed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants