Skip to content

Commit bbe0af8

Browse files
authored
Update docker compose and nginx config (#250)
Resolves #234 This pull request extracts self-hosting documentation from the README into a dedicated SELF_HOSTING.md file and simplifies the Docker Compose configuration for easier deployment. **Key changes:** - Moved comprehensive self-hosting instructions from README.md to SELF_HOSTING.md with expanded details on Docker deployment, environment variables, and custom presets - Switched docker-compose.yml to use the prebuilt image from GitHub Container Registry by default instead of building locally - Embedded the Nginx proxy configuration directly in docker-compose.yml using Docker configs, eliminating the need for external nginx-proxy.conf file dependency - Simplified the Nginx proxy configuration to handle requests at the root path instead of requiring a `/mini-qr/` subpath - Updated port mapping to use standard port 80 for easier access at `http://localhost` The changes make the quick start experience more streamlined - users only need the docker-compose.yml file to get started, while comprehensive customization options are now properly documented in the dedicated self-hosting guide.
1 parent f21e826 commit bbe0af8

4 files changed

Lines changed: 235 additions & 137 deletions

File tree

README.md

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -88,98 +88,7 @@ https://github.com/lyqht/mini-qr/assets/35736525/991b2d7e-f168-4354-9091-1678d2c
8888

8989
## Self-hosting
9090

91-
### Self-hosting with Docker 🐋
92-
93-
Mini-QR can easily be self-hosted using Docker. We provide a [docker-compose.yml](docker-compose.yml) file and a production-ready multi-stage [Dockerfile](Dockerfile).
94-
95-
Quick Start (using prebuilt image)
96-
97-
```bash
98-
wget https://github.com/lyqht/mini-qr/raw/main/docker-compose.yml
99-
100-
docker compose up -d
101-
```
102-
103-
This will pull the latest production image from GitHub Container Registry and start the app at [http://localhost:8081](http://localhost:8081).
104-
105-
To build and run locally (for development or custom builds)
106-
107-
```bash
108-
docker compose up -d --build
109-
```
110-
111-
Or build and run manually:
112-
113-
```bash
114-
docker build -t mini-qr .
115-
docker run -d -p 8081:8080 mini-qr
116-
```
117-
118-
### Self-hosting without Docker 🌐
119-
120-
You can also simply compile the application directly using NPM and Vite like follows:
121-
122-
```bash
123-
git clone https://github.com/lyqht/mini-qr.git
124-
cd mini-qr
125-
npm install
126-
npm run build
127-
```
128-
129-
From there, the application will be build into `dist` folder and this folder can simply be hosted from any kind of web server.
130-
131-
An example using PHP's built-in web server:
132-
133-
```bash
134-
cd dist
135-
php -S localhost:8080
136-
```
137-
138-
### Customization
139-
140-
An example of a self-hosted website with a modified MiniQR app with specific language and preset: https://qrcode.outils.restosducoeur.org/
141-
142-
#### Environment Variables
143-
144-
| Variable | Description | Default |
145-
| ----------------------------- | ---------------------------------------------------------------------------------- | --------- |
146-
| `BASE_PATH` | Base path for deployment | `/` |
147-
| `VITE_HIDE_CREDITS` | Set to `"true"` to hide credits in the footer | `"false"` |
148-
| `VITE_DEFAULT_PRESET` | Name of the default QR code preset to load (e.g., `"lyqht"`) | `""` |
149-
| `VITE_DEFAULT_DATA_TO_ENCODE` | Default data to encode when the app first loads | `""` |
150-
| `VITE_QR_CODE_PRESETS` | JSON string defining custom QR code presets. E.g., `'[{"name":"c1","data":"hi"}]'` | `"[]"` |
151-
| `VITE_FRAME_PRESET` | Name of the default frame preset to load (e.g., `"default"`) | `""` |
152-
| `VITE_FRAME_PRESETS` | JSON string defining custom frame presets. E.g., `'[{"name":"fA","text":"QR"}]'` | `"[]"` |
153-
| `VITE_DISABLE_LOCAL_STORAGE` | Set to `"true"` to disable loading saved settings from local storage on startup | `"false"` |
154-
155-
### Docker configuration
156-
157-
- You can edit `nginx.conf` or mount your own static files by uncommenting the `volumes` section in `docker-compose.yml`.
158-
- The production image uses Nginx for optimal static file serving.
159-
- The `.dockerignore` file is included for smaller, faster builds.
160-
- Set `BASE_PATH=/your-path` to deploy the app under a subdirectory (e.g., for hosting at `domain.com/your-path`).
161-
- If you want to have a default preset to be fixed, you should set `VITE_DISABLE_LOCAL_STORAGE=true`
162-
163-
#### Examples
164-
165-
Deploy at root path (default):
166-
167-
```bash
168-
docker compose up -d
169-
```
170-
171-
Deploy at subdirectory `/mini-qr`:
172-
173-
```bash
174-
BASE_PATH=/mini-qr docker compose up -d
175-
```
176-
177-
For custom builds with specific BASE_PATH:
178-
179-
```bash
180-
docker build --build-arg BASE_PATH=/mini-qr -t mini-qr .
181-
docker run -d -p 8081:8080 mini-qr
182-
```
91+
For full self-hosting instructions including Docker setup, environment variables, custom presets, and deployment scenarios, see [SELF_HOSTING.md](SELF_HOSTING.md).
18392

18493
## Contributing
18594

SELF_HOSTING.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Self-Hosting
2+
3+
This document covers all the ways to self-host MiniQR.
4+
5+
## With Docker 🐋
6+
7+
### Quick Start (prebuilt image)
8+
9+
Pull the prebuilt image from GitHub Container Registry and start the app:
10+
11+
```bash
12+
wget https://github.com/lyqht/mini-qr/raw/main/docker-compose.yml
13+
docker compose up -d
14+
```
15+
16+
The app will be available at [http://localhost](http://localhost) (port 80, proxied by Nginx).
17+
18+
> **Note:** The `docker-compose.yml` embeds its own Nginx config — you only need this one file for the Quick Start. No other files are required.
19+
20+
### Build Locally
21+
22+
To build from source, clone the repository and replace the `image:` line in `docker-compose.yml` with a `build:` section pointing to the local Dockerfile. Then run:
23+
24+
```bash
25+
docker compose up -d --build
26+
```
27+
28+
Or build and run manually:
29+
30+
```bash
31+
docker build -t mini-qr .
32+
docker run -d -p 80:8080 mini-qr
33+
```
34+
35+
## Without Docker 🌐
36+
37+
Compile the application directly using NPM and Vite:
38+
39+
```bash
40+
git clone https://github.com/lyqht/mini-qr.git
41+
cd mini-qr
42+
npm install
43+
npm run build
44+
```
45+
46+
The application builds into the `dist` folder, which can be served from any web server.
47+
48+
Example using PHP's built-in web server:
49+
50+
```bash
51+
cd dist
52+
php -S localhost:8080
53+
```
54+
55+
## Environment Variables
56+
57+
All `VITE_*` variables are **build-time** arguments — they are baked into the static assets at build time and cannot be changed at runtime without rebuilding the image.
58+
59+
| Variable | `docker-compose.yml` alias | Description | Default |
60+
| ----------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------- | --------- |
61+
| `BASE_PATH` | `BASE_PATH` | URL sub-path for deployment (e.g., `/mini-qr` for `domain.com/mini-qr`) | `/` |
62+
| `VITE_HIDE_CREDITS` | `HIDE_CREDITS` | Set to `"true"` to hide the footer credits | `"false"` |
63+
| `VITE_DEFAULT_PRESET` | `DEFAULT_PRESET` | Name of the default QR code style preset (e.g., `"plain"`, `"lyqht"`) | `""` |
64+
| `VITE_DEFAULT_DATA_TO_ENCODE` | `DEFAULT_DATA` | Default text/URL pre-filled in the QR code input field when the app loads | `""` |
65+
| `VITE_QR_CODE_PRESETS` | `PRESETS` | JSON array of custom QR code presets. See [Custom Presets](#custom-presets) below | `"[]"` |
66+
| `VITE_FRAME_PRESET` | `FRAME_PRESET` | Name of the default frame preset to apply (e.g., `"Default Frame"`) | `""` |
67+
| `VITE_FRAME_PRESETS` | `FRAME_PRESETS` | JSON array of custom frame presets. See [Custom Presets](#custom-presets) below | `"[]"` |
68+
| `VITE_DISABLE_LOCAL_STORAGE` | `DISABLE_LOCAL_STORAGE` | Set to `"true"` to prevent the app from loading previously saved settings on startup | `"false"` |
69+
70+
### Passing Variables via docker-compose
71+
72+
The `docker-compose.yml` maps shorter environment variable names to the full build arg names. Set them on the host before running:
73+
74+
```bash
75+
BASE_PATH=/mini-qr DEFAULT_PRESET=plain DISABLE_LOCAL_STORAGE=true docker compose up -d --build
76+
```
77+
78+
Or create a `.env` file alongside `docker-compose.yml`:
79+
80+
```dotenv
81+
BASE_PATH=/mini-qr
82+
DEFAULT_PRESET=plain
83+
HIDE_CREDITS=false
84+
DISABLE_LOCAL_STORAGE=true
85+
```
86+
87+
Then run:
88+
89+
```bash
90+
docker compose up -d --build
91+
```
92+
93+
### Passing Variables via `docker build`
94+
95+
When building directly, pass each variable as a `--build-arg`:
96+
97+
```bash
98+
docker build \
99+
--build-arg BASE_PATH=/mini-qr \
100+
--build-arg VITE_DEFAULT_PRESET=plain \
101+
--build-arg VITE_DISABLE_LOCAL_STORAGE=true \
102+
-t mini-qr .
103+
```
104+
105+
## Custom Presets
106+
107+
### QR Code Presets (`VITE_QR_CODE_PRESETS`)
108+
109+
A JSON array of preset objects. Each preset overrides the visual style of the QR code. Required fields: `name`. All standard `qr-code-styling` options are supported.
110+
111+
```json
112+
[
113+
{
114+
"name": "My Brand",
115+
"dotsOptions": { "color": "#ff0000", "type": "rounded" },
116+
"cornersSquareOptions": { "color": "#ff0000", "type": "extra-rounded" },
117+
"cornersDotOptions": { "color": "#ff0000" },
118+
"backgroundOptions": { "color": "#ffffff" }
119+
}
120+
]
121+
```
122+
123+
Pass as a build arg (escape the JSON or use a `.env` file):
124+
125+
```bash
126+
PRESETS='[{"name":"My Brand","dotsOptions":{"color":"#ff0000","type":"rounded"}}]' docker compose up -d --build
127+
```
128+
129+
### Frame Presets (`VITE_FRAME_PRESETS`)
130+
131+
A JSON array of frame preset objects. Each preset defines the style and optional default text for the frame surrounding the QR code.
132+
133+
```json
134+
[
135+
{
136+
"name": "Red Frame",
137+
"text": "Scan me",
138+
"position": "bottom",
139+
"style": {
140+
"textColor": "#ffffff",
141+
"backgroundColor": "#cc0000",
142+
"borderColor": "#cc0000",
143+
"borderWidth": "2px",
144+
"borderRadius": "8px",
145+
"padding": "12px"
146+
}
147+
}
148+
]
149+
```
150+
151+
## Deployment Scenarios
152+
153+
### Deploy at root path (default)
154+
155+
```bash
156+
docker compose up -d
157+
```
158+
159+
### Deploy at a subdirectory
160+
161+
```bash
162+
BASE_PATH=/mini-qr docker compose up -d --build
163+
```
164+
165+
### Fixed preset with localStorage disabled
166+
167+
Useful when embedding MiniQR in a branded context where users should always see the configured preset:
168+
169+
```bash
170+
DEFAULT_PRESET=plain DISABLE_LOCAL_STORAGE=true docker compose up -d --build
171+
```
172+
173+
### Hide footer credits
174+
175+
```bash
176+
HIDE_CREDITS=true docker compose up -d --build
177+
```
178+
179+
## Nginx Proxy
180+
181+
The `docker-compose.yml` includes an `nginx-proxy` service that proxies traffic to the MiniQR app container. The Nginx configuration is embedded inline in `docker-compose.yml` under the `configs:` key, so no extra files are needed for the Quick Start.
182+
183+
To override the Nginx config (e.g. for subdirectory deployment or custom headers), replace the `configs.nginx-proxy-conf.content` block in `docker-compose.yml` with your own configuration, or switch to a file-based mount:
184+
185+
```yaml
186+
volumes:
187+
- ./nginx-proxy.conf:/etc/nginx/nginx.conf:ro
188+
```
189+
190+
## Customization Example
191+
192+
An example of a self-hosted website with a modified MiniQR app with specific language and preset: https://qrcode.outils.restosducoeur.org/

docker-compose.yml

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
11
---
22
services:
33
mini-qr:
4-
# image: ghcr.io/lyqht/mini-qr:latest
4+
image: ghcr.io/lyqht/mini-qr:latest
55
container_name: mini-qr
66
restart: unless-stopped
7-
# Uncomment the following lines to build locally instead of pulling from ghcr.io
8-
build:
9-
context: .
10-
dockerfile: Dockerfile
11-
args:
12-
- BASE_PATH=${BASE_PATH:-/mini-qr/}
13-
- VITE_HIDE_CREDITS=${HIDE_CREDITS:-false}
14-
- VITE_DEFAULT_PRESET=${DEFAULT_PRESET:-}
15-
- VITE_DEFAULT_DATA_TO_ENCODE=${DEFAULT_DATA:-}
16-
- VITE_QR_CODE_PRESETS=${PRESETS:-}
17-
- VITE_FRAME_PRESET=${FRAME_PRESET:-}
18-
- VITE_FRAME_PRESETS=${FRAME_PRESETS:-}
19-
- VITE_DISABLE_LOCAL_STORAGE=${DISABLE_LOCAL_STORAGE:-false}
20-
# volumes:
21-
# - ./public:/usr/share/nginx/html/public:ro
22-
# - ./nginx.conf:/etc/nginx/nginx.conf:ro
237
networks:
248
- mini-qr-network
259

@@ -29,13 +13,50 @@ services:
2913
ports:
3014
- 80:80
3115
restart: unless-stopped
32-
volumes:
33-
- ./nginx-proxy.conf:/etc/nginx/nginx.conf:ro
16+
configs:
17+
- source: nginx-proxy-conf
18+
target: /etc/nginx/nginx.conf
3419
depends_on:
3520
- mini-qr
3621
networks:
3722
- mini-qr-network
3823

24+
configs:
25+
nginx-proxy-conf:
26+
content: |
27+
events {
28+
worker_connections 1024;
29+
}
30+
http {
31+
include /etc/nginx/mime.types;
32+
default_type application/octet-stream;
33+
sendfile on;
34+
keepalive_timeout 65;
35+
upstream mini-qr-backend {
36+
server mini-qr:8080;
37+
}
38+
server {
39+
listen 80;
40+
server_name localhost;
41+
location / {
42+
proxy_pass http://mini-qr-backend;
43+
proxy_set_header Host $$host;
44+
proxy_set_header X-Real-IP $$remote_addr;
45+
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
46+
proxy_set_header X-Forwarded-Proto $$scheme;
47+
}
48+
location /health {
49+
access_log off;
50+
return 200 "healthy\n";
51+
add_header Content-Type text/plain;
52+
}
53+
error_page 500 502 503 504 /50x.html;
54+
location = /50x.html {
55+
root /usr/share/nginx/html;
56+
}
57+
}
58+
}
59+
3960
networks:
4061
mini-qr-network:
4162
driver: bridge

0 commit comments

Comments
 (0)