From 4223ba2f1eb08958394ed6e7e3bad2768c45da9a Mon Sep 17 00:00:00 2001 From: Schuwi Date: Tue, 16 Sep 2025 14:01:09 +0200 Subject: [PATCH] build(elixir): add dev container --- .devcontainer/Dockerfile | 47 +++++++++++ .devcontainer/README.md | 134 ++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 59 ++++++++++++++ .devcontainer/setup.sh | 39 ++++++++++ 4 files changed, 279 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json create mode 100755 .devcontainer/setup.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..fd00a8d --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,47 @@ +# Use the official Elixir image with OTP 26 and Elixir 1.15 +FROM elixir:1.15-otp-26-slim + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + curl \ + build-essential \ + inotify-tools \ + postgresql-client \ + sudo \ + && rm -rf /var/lib/apt/lists/* + +# Install Node.js 20 (needed for assets compilation) +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs + +# Create a non-root user +RUN groupadd --gid 1000 vscode \ + && useradd --uid 1000 --gid vscode --shell /bin/bash --create-home vscode \ + && echo 'vscode ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +# Set the working directory +WORKDIR /workspace + +# Copy the project files +COPY --chown=vscode:vscode . /workspace + +# Install Hex and Rebar +RUN mix local.hex --force && \ + mix local.rebar --force + +# Switch to vscode user +USER vscode + +# Install Phoenix +RUN mix archive.install hex phx_new --force + +# Set environment variables +ENV MIX_ENV=dev +ENV PHX_SERVER=true + +# Expose port 4000 for Phoenix +EXPOSE 4000 + +# Default command +CMD ["tail", "-f", "/dev/null"] \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..3417a8f --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,134 @@ +# Development Container Setup + +This devcontainer provides a complete Elixir Phoenix development environment with all necessary tools and dependencies pre-installed. + +## What's Included + +- **Elixir 1.15** with OTP 26 +- **Phoenix Framework** (latest) +- **Node.js 20** for asset compilation +- **PostgreSQL 15** database +- **VS Code Extensions** for Elixir/Phoenix development +- **Development tools**: Git, build tools, inotify-tools + +## Quick Start + +1. Open this project in VS Code +2. Install the "Dev Containers" extension if you haven't already +3. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac) and select "Dev Containers: Reopen in Container" +4. Wait for the container to build and initialize +5. The setup script will automatically run to configure your environment + +## What Happens During Setup + +The `setup.sh` script automatically: +- Installs Elixir dependencies (`mix deps.get`) +- Installs Node.js dependencies for assets +- Creates and migrates the database +- Runs database seeds (if available) +- Compiles the project + +## Development Workflow + +### Starting the Phoenix Server +```bash +mix phx.server +``` +The server will be available at http://localhost:4000 + +### Database Operations +```bash +# Reset database +mix ecto.reset + +# Create migration +mix ecto.gen.migration migration_name + +# Run migrations +mix ecto.migrate + +# Rollback migration +mix ecto.rollback +``` + +### Testing +```bash +# Run all tests +mix test + +# Run specific test file +mix test test/path/to/test_file.exs + +# Run tests with coverage +mix test --cover +``` + +### Asset Management +```bash +# Install new npm packages +cd assets && npm install package-name && cd .. + +# Build assets for production +mix assets.deploy +``` + +## VS Code Extensions Included + +- **ElixirLS** - Language server for Elixir +- **Phoenix Framework** - Phoenix-specific tooling +- **Tailwind CSS IntelliSense** - CSS utility suggestions +- **Prettier** - Code formatting +- **GitHub Copilot** - AI-powered code completion +- **Auto Rename Tag** - HTML tag synchronization + +## Environment Variables + +The following environment variables are pre-configured: +- `MIX_ENV=dev` +- `PHX_SERVER=true` +- `DATABASE_URL=ecto://postgres:postgres@db:5432/components_elixir_dev` + +## Ports + +The following ports are forwarded to your local machine: +- **4000** - Phoenix web server +- **5433** - PostgreSQL database (mapped to avoid conflicts with host PostgreSQL) + +## Persistent Storage + +The following directories are stored in Docker volumes for better performance: +- `_build/` - Compiled Elixir code +- `deps/` - Elixir dependencies +- `assets/node_modules/` - Node.js dependencies +- PostgreSQL data + +## Troubleshooting + +### Container won't start +- Make sure Docker is running +- Try rebuilding the container: "Dev Containers: Rebuild Container" + +### Port conflicts +- If you get "port is already allocated" errors, make sure no other containers are using the same ports +- Stop existing containers: `docker-compose down` +- The devcontainer uses port 5433 for PostgreSQL to avoid conflicts with host installations + +### Database connection issues +- Ensure the database service is running: `docker-compose ps` +- Check database logs: `docker-compose logs db` + +### Permission issues +- The container runs as user `vscode` (UID 1000) +- If you encounter permission issues, rebuild the container + +### Dependencies not installing +- Try running `mix deps.clean --all && mix deps.get` +- For Node.js: `cd assets && rm -rf node_modules && npm install` + +## Customization + +You can customize the development environment by: +- Modifying `.devcontainer/devcontainer.json` for VS Code settings +- Updating `.devcontainer/Dockerfile` for additional system packages +- Editing `.devcontainer/docker-compose.yml` for service configuration +- Adding to `.devcontainer/setup.sh` for additional setup steps \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..0711978 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,59 @@ +{ + "name": "Elixir Phoenix Components", + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspace", + // Features to install + "features": { + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 4000, + 5433 + ], + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "JakeBecker.elixir-ls", + "phoenixframework.phoenix", + "ms-vscode.vscode-json", + "bradlc.vscode-tailwindcss", + "ms-vscode.hexeditor", + "GitHub.copilot", + "GitHub.copilot-chat", + "ms-vscode.test-adapter-converter", + "hbenl.vscode-test-explorer", + "formulahendry.auto-rename-tag", + "esbenp.prettier-vscode" + ], + "settings": { + "terminal.integrated.defaultProfile.linux": "bash", + "elixirLS.dialyzerEnabled": true, + "elixirLS.fetchDeps": false, + "elixirLS.suggestSpecs": true, + "files.associations": { + "*.heex": "html", + "*.ex": "elixir", + "*.exs": "elixir" + }, + "emmet.includeLanguages": { + "html": "html", + "elixir": "html" + }, + "editor.formatOnSave": true, + "[elixir]": { + "editor.defaultFormatter": "JakeBecker.elixir-ls" + } + } + } + }, + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "bash .devcontainer/setup.sh", + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + // Keep container running for faster subsequent starts + "shutdownAction": "stopContainer" +} \ No newline at end of file diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 0000000..150aebd --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Setup script for Elixir Phoenix development environment + +echo "🚀 Setting up Elixir Phoenix development environment..." + +# Install dependencies +echo "📦 Installing Elixir dependencies..." +mix deps.get + +# Install Node.js dependencies for assets +echo "📦 Installing Node.js dependencies..." +cd assets && npm install && cd .. + +# Create and migrate database +echo "🗃️ Setting up database..." +mix ecto.create +mix ecto.migrate + +# Run seeds if they exist +if [ -f priv/repo/seeds.exs ]; then + echo "🌱 Running database seeds..." + mix run priv/repo/seeds.exs +fi + +# Compile the project +echo "🔨 Compiling project..." +mix compile + +echo "✅ Development environment setup complete!" +echo "" +echo "🎯 Quick start commands:" +echo " mix phx.server - Start the Phoenix server" +echo " mix test - Run tests" +echo " mix deps.get - Install dependencies" +echo " mix ecto.migrate - Run database migrations" +echo " mix ecto.reset - Reset database" +echo "" +echo "🌐 Phoenix server will be available at http://localhost:4000" \ No newline at end of file