Merge pull request #159 from blacksigkill/it/dockerization

Enhance dockerization with modular docker file/compose
This commit is contained in:
Eduard Prigoana 2026-02-06 23:24:13 +02:00 committed by GitHub
commit 6ede597b6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 349 additions and 12 deletions

32
.dockerignore Normal file
View file

@ -0,0 +1,32 @@
# Dependencies
node_modules
# Build output
dist
# Git
.git
.github
# IDE
.idea
.vscode
# OS
.DS_Store
# Environment
.env
.env.*
# Documentation
*.md
license
# Docker
Dockerfile*
docker-compose*.yml
.dockerignore
# Other
*.log

12
.env.example Normal file
View file

@ -0,0 +1,12 @@
# Monochrome Docker Configuration
# Copy to .env and edit: cp .env.example .env
# --- Monochrome ---
MONOCHROME_PORT=3000
MONOCHROME_DEV_PORT=5173
# --- PocketBase (only used with --profile pocketbase) ---
POCKETBASE_PORT=8090
PB_ADMIN_EMAIL=admin@example.com
PB_ADMIN_PASSWORD=changeme
TZ=UTC

3
.gitignore vendored
View file

@ -3,3 +3,6 @@ dist
.DS_Store
*.local
.vite
# Docker
.env

187
DOCKER.md Normal file
View file

@ -0,0 +1,187 @@
# Docker Deployment Guide
## Quick Start
### Monochrome Only
```bash
docker compose up -d
```
Visit `http://localhost:3000`
### With PocketBase
```bash
cp .env.example .env
# Edit .env -- set PB_ADMIN_EMAIL and PB_ADMIN_PASSWORD
docker compose --profile pocketbase up -d
```
- Monochrome: `http://localhost:3000`
- PocketBase admin: `http://localhost:8090/_/`
Configure PocketBase collections per [self-hosted-database.md](self-hosted-database.md).
### Development
```bash
docker compose --profile dev up -d
```
Visit `http://localhost:5173` (hot-reload enabled)
---
## How It Works
### Profiles
Docker Compose [profiles](https://docs.docker.com/compose/how-tos/profiles/) control which services start. A service with no profile always runs. A service with a profile only runs when that profile is activated.
| Command | What starts |
| --------------------------------------------------------- | ------------------------------------ |
| `docker compose up -d` | Monochrome |
| `docker compose --profile pocketbase up -d` | Monochrome + PocketBase |
| `docker compose --profile dev up -d` | Monochrome + Dev server |
| `docker compose --profile dev --profile pocketbase up -d` | Monochrome + Dev server + PocketBase |
In `docker-compose.yml`, it looks like this:
```yaml
services:
monochrome: # no profile -- always starts
pocketbase:
profiles: ['pocketbase'] # opt-in
monochrome-dev:
profiles: ['dev'] # opt-in
```
### Override File
Docker Compose automatically merges `docker-compose.override.yml` into `docker-compose.yml` if it exists in the same directory. No flags needed.
This is useful for forks that need to add custom services or configuration (Traefik labels, extra containers, custom networks) without modifying the base `docker-compose.yml`.
The override file does not exist in the upstream repo, don't search it!
**Example** -- adding Traefik labels to PocketBase in your fork:
```yaml
# docker-compose.override.yml
services:
pocketbase:
labels:
- traefik.enable=true
- traefik.http.routers.pocketbase.rule=Host(`pocketbase.example.com`)
- traefik.http.routers.pocketbase.entrypoints=websecure
- traefik.http.routers.pocketbase.tls.certresolver=letsencrypt
- traefik.http.services.pocketbase.loadbalancer.server.port=8090
networks:
- proxy-network
networks:
proxy-network:
external: true
```
**Example** -- adding a custom service in your fork:
```yaml
# docker-compose.override.yml
services:
my-custom-api:
image: my-api:latest
restart: unless-stopped
ports:
- '4000:4000'
networks:
- monochrome-network
```
Override files can extend existing services (add labels, env vars, networks) and define entirely new services. See the [Docker docs](https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/) for the full merge behavior.
---
## Portainer Deployment
Portainer can deploy directly from your GitHub fork with auto-updates on push.
### Setup
1. In Portainer, go to **Stacks > Add Stack > Repository**
2. Enter your fork URL and branch
3. Compose path: `docker-compose.yml`
4. If your fork has a `docker-compose.override.yml`, Portainer loads it automatically
5. Under **Environment variables**, add:
- `COMPOSE_PROFILES=pocketbase` (to enable PocketBase -- omit if not needed)
- `PB_ADMIN_EMAIL=your@email.com`
- `PB_ADMIN_PASSWORD=your_secure_password`
- Any other variables from `.env.example`
6. Enable **GitOps updates** to auto-redeploy on push
> **Tip:** `COMPOSE_PROFILES` is a built-in Docker Compose variable. Setting it to `pocketbase` is equivalent to passing `--profile pocketbase` on the command line.
> **Warning:** The `dev` profile is for **local development only**. It uses volume mounts to enable hot-reload, which requires the source code to be present on the host machine. Do **not** include `dev` in `COMPOSE_PROFILES` on Portainer deployments from GitHub — it will fail because there's no local source code to mount.
### Fork Workflow
To add custom services (Traefik, monitoring, etc.) to your fork:
1. Create `docker-compose.override.yml` in your fork
2. Remove the `docker-compose.override.yml` line from `.gitignore`
3. Commit both changes to your fork
4. Portainer will auto-load the override file alongside the base compose
When pulling updates from upstream (`git pull upstream main`), there are no conflicts -- the upstream repo does not have an override file.
---
## Common Operations
```bash
# View logs
docker compose logs -f
docker compose logs -f pocketbase
# Rebuild after code changes
docker compose up -d --build
# Stop everything (include all profiles you started)
docker compose --profile pocketbase down
# Stop and remove volumes (data loss!)
docker compose --profile pocketbase down -v
# Backup PocketBase data
docker compose exec pocketbase tar czf - /pb_data > backup.tar.gz
# Restore PocketBase data
docker compose exec pocketbase tar xzf - -C / < backup.tar.gz
```
---
## Architecture
### Production (Dockerfile)
Node.js Alpine image (multi-arch: amd64 + arm64). Installs dependencies, runs `vite build`, then serves the built files with `vite preview` on port 4173.
### Development (Dockerfile.dev)
Node.js Alpine image with source code mounted as a volume for hot-reload.
### Files
| File | Purpose | In upstream repo |
| ----------------------------- | ----------------------------- | :--------------: |
| `docker-compose.yml` | All services with profiles | Yes |
| `docker-compose.override.yml` | Fork-specific customizations | No |
| `.env.example` | Environment variable template | Yes |
| `.env` | Your local configuration | No |
| `Dockerfile` | Production build | Yes |
| `Dockerfile.dev` | Development build | Yes |
| `.dockerignore` | Build context exclusions | Yes |

View file

@ -1,23 +1,25 @@
# Use Bun canary on Alpine
FROM oven/bun:canary-alpine
# Node Alpine -- multi-arch (amd64 + arm64)
FROM node:lts-alpine
# Set working directory
WORKDIR /app
# Copy package files first for caching
COPY package.json bun.lock ./
# wget is needed for Docker healthcheck
RUN apk add --no-cache wget
# Install all dependencies (including devDeps)
RUN bun install
# Copy package files first for caching
COPY package.json ./
# Install dependencies
RUN npm install
# Copy the rest of the project
COPY . .
# Build the project
RUN bun run build
RUN npm run build
# Expose Vite preview port
EXPOSE 4173
# Run the built project
CMD ["bun", "run", "preview", "--", "--host", "0.0.0.0"]
CMD ["npm", "run", "preview", "--", "--host", "0.0.0.0"]

16
Dockerfile.dev Normal file
View file

@ -0,0 +1,16 @@
# Development Dockerfile for hot-reloading
# Node Alpine -- multi-arch (amd64 + arm64)
FROM node:lts-alpine
WORKDIR /app
# Copy package files first for caching
COPY package.json ./
# Install dependencies
RUN npm install
# Expose Vite dev server port
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]

View file

@ -107,12 +107,26 @@ For alternative instances, check [INSTANCES.md](INSTANCES.md).
NOTE: Accounts wont work on self-hosted instances.
### Prerequisites
### Option 1: Docker (Recommended)
```bash
git clone https://github.com/monochrome-music/monochrome.git
cd monochrome
docker compose up -d
```
Visit `http://localhost:3000`
For PocketBase, development mode, and advanced setups, see [DOCKER.md](DOCKER.md).
### Option 2: Manual Installation
#### Prerequisites
- [Node.js](https://nodejs.org/) (Version 20+ or 22+ recommended)
- [Bun](https://bun.sh/) or [npm](https://www.npmjs.com/)
### Local Development
#### Local Development
1. **Clone the repository:**
@ -140,7 +154,7 @@ NOTE: Accounts wont work on self-hosted instances.
4. **Open your browser:**
Navigate to `http://localhost:5173/`
### Building for Production
#### Building for Production
```bash
bun run build

71
docker-compose.yml Normal file
View file

@ -0,0 +1,71 @@
services:
# Production frontend -- always runs
monochrome:
build:
context: .
dockerfile: Dockerfile
container_name: monochrome
ports:
- '${MONOCHROME_PORT:-3000}:4173'
restart: unless-stopped
networks:
- monochrome-network
healthcheck:
test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:4173/']
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
# PocketBase backend -- only starts with: docker compose --profile pocketbase up -d
pocketbase:
image: ghcr.io/muchobien/pocketbase:latest
container_name: monochrome-pocketbase
profiles:
- pocketbase
restart: unless-stopped
environment:
PB_ADMIN_EMAIL: ${PB_ADMIN_EMAIL:-admin@example.com}
PB_ADMIN_PASSWORD: ${PB_ADMIN_PASSWORD:-changeme}
TZ: ${TZ:-UTC}
ports:
- '${POCKETBASE_PORT:-8090}:8090'
volumes:
- pb_data:/pb_data
- pb_public:/pb_public
- pb_hooks:/pb_hooks
command: serve --http=0.0.0.0:8090
healthcheck:
test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:8090/api/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
- monochrome-network
# Development server -- only starts with: docker compose --profile dev up -d
monochrome-dev:
build:
context: .
dockerfile: Dockerfile.dev
container_name: monochrome-dev
profiles:
- dev
ports:
- '${MONOCHROME_DEV_PORT:-5173}:5173'
volumes:
- .:/app
- /app/node_modules
command: npm run dev -- --host 0.0.0.0
networks:
- monochrome-network
networks:
monochrome-network:
driver: bridge
volumes:
pb_data:
pb_public:
pb_hooks: