Skip to content

Set up a local development environment

← Maintainer handbook · Configuration · CLI reference · Testing

You do not need to install the project to browse internships. Use the live directory.

Install the development tools, initialize disposable local SQLite state, and launch the website without collecting listings. Runtime settings, production operations, and contribution procedures have separate guides.

Requirements

Tool Version Required for
Python 3.12+ (CI baseline: 3.12) Pipeline, CLI, tests, and migrations
uv 0.13.4 recommended Locked Python environment and commands
Git Current supported release Repository checkout
Node.js 22.13+ Website builds and production-style local startup with unflagged node:sqlite support
Bun 1.4.3 Website dependency installation, tests, and development
GNU Make Optional Python validation shortcuts; direct uv commands are documented too
Docker Current supported release Documentation lint and optional container and deployment checks

Confirm the required tools:

python --version
uv --version
git --version
node --version
bun --version

Docker is not required for ordinary local Python or website development, but the complete make check and make docs-site gates include the Docker-based documentation linters. Installation, local website development, and the default test paths require no LinkedIn access.

Clone the repository

git clone https://github.com/simonesiega/european-tech-opportunities-2027.git
cd european-tech-opportunities-2027

Run the remaining Python commands from the repository root unless a section explicitly changes directory.

Install the Python project

Install the exact locked development environment:

uv sync --frozen --dev

Create the local environment file.

Linux or macOS:

cp .env.example .env

Windows Command Prompt:

copy .env.example .env

Windows PowerShell:

Copy-Item .env.example .env

The default configuration keeps LinkedIn collection disabled. Review the configuration guide before changing runtime values.

Initialize the local database

Confirm the configured database path is a new, disposable development path before running this command. Do not use a production database or a shared operator working copy.

Create or upgrade the SQLite schema:

uv run opportunities db-upgrade

Verify that the search registry and database load:

uv run opportunities searches
uv run opportunities stats

The default database is created at:

data/opportunities.db

A new local database intentionally contains no listings. Use the hosted directory for current public data.

Important

Do not render and commit the README preview from an empty local database. Exact projection rendering requires representative canonical state.

Run the website

Install the website dependencies:

cd site
bun install --frozen-lockfile

Create the website environment file.

Linux or macOS:

cp .env.example .env.local

Windows Command Prompt:

copy .env.example .env.local

Windows PowerShell:

Copy-Item .env.example .env.local

For local development, make sure site/.env.local uses the local origin and disposable paths below. Leave OPPORTUNITIES_RELEASE_ROOT unset so it cannot override them:

SITE_URL=http://localhost:3000
OPPORTUNITIES_DATABASE_PATH=../data/opportunities.db
OPPORTUNITIES_PUBLIC_EXPORT_DIR=../data/exports

Start the development server:

bun run dev

Open:

http://localhost:3000

The website reads SQLite and pipeline-generated public exports in read-only mode. An empty directory is valid when the local database contains no open listings; run uv run opportunities export-public from the repository root to create empty local CSV/JSON projections when testing the download routes.

For realistic synthetic listings without collection, run bun run test:e2e:setup from site/. This requires the Python environment above and uses real migrations, repository writes, and export serialization. For an interactive session, point the site at absolute paths to site/tests/e2e/.tmp/opportunities.db and site/tests/e2e/.tmp/, with OPPORTUNITIES_RELEASE_ROOT unset. These disposable files are never production state. Tour reproduction runs an isolated fixed-clock instance automatically.

After stopping the development server, return to the repository root:

cd ..

Verify the installation

From the repository root, verify the Python project:

uv run opportunities --help
uv run opportunities stats
uv run pytest -m "not live and not performance"

Install Chromium once before running the complete website validation path:

cd site
bunx playwright install chromium

Then verify the website:

bun run ci
cd ..

bun run ci checks formatting, linting, strict TypeScript, the production Next.js build, Bun unit tests, Playwright browser behavior, and axe-core accessibility against a generated SQLite fixture.

The complete engineering validation matrix is documented in the testing guide.

Docker

Docker is optional for running the Python project or website directly. It is required for the pinned documentation linters included in the full validation gates.

For image builds, Compose services, volumes, permissions, local container access, and Dokploy deployment, use the containers and deployment guide.