Skip to content

Commit aa9dc7d

Browse files
committed
Enhance Docker setup and documentation
- Update .dockerignore to exclude sources configuration files - Add Docker deployment instructions in DOCKER_DEPLOYMENT.md - Modify Dockerfile to clarify sources.yaml mounting - Update docker-compose files to mount sources.yaml and tmpfw directory - Implement health check endpoint in docker-compose configurations - Add error handling for missing sources.yaml in docker-entrypoint.sh - Remove outdated firmware flashing scripts - Introduce new sources_example.yaml with example firmware configurations
1 parent 87b6b69 commit aa9dc7d

13 files changed

+171
-733
lines changed

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
.gitignore
44
.github
55

6+
# Sources configuration files (must be mounted from outside)
7+
sources.yaml
8+
sources_example.yaml
9+
sources*.yaml
10+
611
# Python
712
__pycache__
813
*.pyc

DOCKER_DEPLOYMENT.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Docker Deployment Instructions
2+
3+
## Quick Start
4+
5+
1. **Create your sources configuration:**
6+
```bash
7+
cp sources_example.yaml sources.yaml
8+
# Edit sources.yaml with your firmware repositories
9+
```
10+
11+
2. **Start the container:**
12+
```bash
13+
docker-compose up -d
14+
```
15+
16+
3. **Access the web interface:**
17+
Open http://localhost:8000 in your browser
18+
19+
## Configuration Files
20+
21+
### sources.yaml (Required)
22+
The `sources.yaml` file defines which firmware repositories to fetch from. It **must** be mounted from outside the container for security and flexibility.
23+
24+
**Example:**
25+
```yaml
26+
fetchdir: ./tmpfw
27+
28+
sources:
29+
- type: github
30+
platform: pio
31+
name: my-firmware
32+
repo: user/my-esp32-firmware
33+
asset_pattern: "^firmware-esp32-${revision}.bin$"
34+
```
35+
36+
### Volume Mounts
37+
38+
| Host Path | Container Path | Description |
39+
|-----------|---------------|-------------|
40+
| `./sources.yaml` | `/app/sources.yaml:ro` | **Required** - Firmware source configuration |
41+
| `./tmpfw` | `/app/tmpfw` | Firmware download directory |
42+
| `./img` | `/app/img:ro` | Optional custom firmware images |
43+
| `/dev` | `/dev` | USB device access |
44+
45+
## Docker Compose Files
46+
47+
- `docker-compose.yml` - Development setup with live reload
48+
- `docker-compose.production.yml` - Production setup with published image
49+
- `docker-compose.production-pinned.yml` - Production with pinned version
50+
- `docker-compose.production-secure.yml` - Production with limited device access
51+
- `examples/docker-compose.extended.yml` - Extended setup with custom features
52+
53+
## Security Notes
54+
55+
- The `sources.yaml` file is **never** included in the Docker image
56+
- Always mount it as read-only (`:ro`)
57+
- Use `docker-compose.production-secure.yml` for production environments
58+
- Consider running without `privileged: true` by mapping specific TTY devices
59+
60+
## Troubleshooting
61+
62+
### Container fails to start with "sources.yaml not found"
63+
```bash
64+
# Make sure you have a sources.yaml file in your current directory
65+
ls -la sources.yaml
66+
67+
# If not, create one from the example
68+
cp sources_example.yaml sources.yaml
69+
```
70+
71+
### No firmware appears in web interface
72+
```bash
73+
# Check if tmpfw directory has content
74+
ls -la tmpfw/
75+
76+
# Check container logs
77+
docker-compose logs webuiflasher
78+
```
79+
80+
### USB devices not detected
81+
```bash
82+
# Check if devices are mapped correctly
83+
docker-compose exec webuiflasher ls -la /dev/ttyUSB* /dev/ttyACM*
84+
85+
# For secure setup, adjust device mappings in docker-compose.production-secure.yml
86+
```

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ WORKDIR /app
1818
# Copy project files
1919
COPY pyproject.toml uv.lock ./
2020
COPY scripts/ ./scripts/
21-
COPY sources.yaml ./
21+
# NOTE: sources.yaml and sources_example.yaml are NOT copied - they must be mounted from outside
2222
COPY img/ ./img/
2323
COPY README.md ./
2424
COPY docker-entrypoint.sh ./
@@ -41,7 +41,7 @@ EXPOSE 8000
4141

4242
# Add healthcheck
4343
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
44-
CMD curl -f http://localhost:8000/api/firmware || exit 1
44+
CMD curl -f http://localhost:8000/health || exit 1
4545

4646
# Set entrypoint (using root for better device access)
4747
ENTRYPOINT ["./docker-entrypoint.sh"]

docker-compose.production-pinned.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
version: '3.8'
22

3-
healthcheck:
4-
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
5-
interval: 30s
6-
timeout: 10s
7-
retries: 3
8-
start_period: 40ses:
3+
services:
94
webuiflasher:
10-
image: ghcr.io/the78mole/webuiflasher:v1.0.0
5+
image: ghcr.io/the78mole/webuiflasher:v0.0.9
116
container_name: webuiflasher-pinned
127
ports:
138
- "8000:8000"
149
volumes:
15-
- ./firmware:/app/firmware
16-
- ./sources:/app/sources
10+
# Mount firmware download directory
11+
- ./tmpfw:/app/tmpfw
12+
# Mount sources configuration (external injection)
13+
- ./sources.yaml:/app/sources.yaml:ro
14+
# Optional: Mount custom firmware sources
15+
- ./img:/app/img:ro
16+
# Mount entire /dev for USB access
1717
- /dev:/dev
1818
privileged: true
1919
restart: unless-stopped
2020
environment:
2121
- TZ=Europe/Berlin
22+
- PYTHONUNBUFFERED=1
23+
- WEBFLASHER_HOST=0.0.0.0
24+
- WEBFLASHER_PORT=8000
2225
healthcheck:
2326
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
2427
interval: 30s

docker-compose.production-secure.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@ services:
77
ports:
88
- "8000:8000"
99
volumes:
10-
- ./firmware:/app/firmware
11-
- ./sources:/app/sources
10+
# Mount firmware download directory
11+
- ./tmpfw:/app/tmpfw
12+
# Mount sources configuration (external injection)
13+
- ./sources.yaml:/app/sources.yaml:ro
14+
# Optional: Mount custom firmware sources
15+
- ./img:/app/img:ro
1216
# Specific TTY devices only (adjust as needed)
1317
- /dev/ttyUSB0:/dev/ttyUSB0
1418
- /dev/ttyUSB1:/dev/ttyUSB1
1519
- /dev/ttyACM0:/dev/ttyACM0
1620
restart: unless-stopped
1721
environment:
1822
- TZ=Europe/Berlin
23+
- PYTHONUNBUFFERED=1
24+
- WEBFLASHER_HOST=0.0.0.0
25+
- WEBFLASHER_PORT=8000
1926
healthcheck:
2027
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
2128
interval: 30s

docker-compose.production.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,21 @@ services:
77
ports:
88
- "8000:8000"
99
volumes:
10-
- ./firmware:/app/firmware
11-
- ./sources:/app/sources
10+
# Mount firmware download directory
11+
- ./tmpfw:/app/tmpfw
12+
# Mount sources configuration (external injection)
13+
- ./sources.yaml:/app/sources.yaml:ro
14+
# Optional: Mount custom firmware sources
15+
- ./img:/app/img:ro
16+
# Mount entire /dev for USB access
1217
- /dev:/dev
1318
privileged: true
1419
restart: unless-stopped
1520
environment:
1621
- TZ=Europe/Berlin
22+
- PYTHONUNBUFFERED=1
23+
- WEBFLASHER_HOST=0.0.0.0
24+
- WEBFLASHER_PORT=8000
1725
healthcheck:
1826
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
1927
interval: 30s

docker-entrypoint.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ else
1919
echo "⚠️ No USB devices found. Make sure devices are mapped in docker-compose.yml"
2020
fi
2121

22+
# Check if sources.yaml exists (must be mounted from outside)
23+
if [ ! -f "/app/sources.yaml" ]; then
24+
echo "❌ ERROR: sources.yaml not found!"
25+
echo "💡 You must mount a sources.yaml file from outside the container:"
26+
echo " -v ./your-sources.yaml:/app/sources.yaml:ro"
27+
echo "📝 See sources_example.yaml for reference"
28+
exit 1
29+
else
30+
echo "✅ Found sources.yaml configuration"
31+
fi
32+
2233
# Download firmware if tmpfw is empty
2334
if [ ! "$(ls -A /app/tmpfw 2>/dev/null)" ]; then
2435
echo "📥 Downloading firmware..."

examples/docker-compose.extended.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ services:
99
ports:
1010
- "8000:8000"
1111
volumes:
12-
- ./firmware:/app/firmware
13-
- ./sources:/app/sources
12+
# Mount firmware download directory
13+
- ./tmpfw:/app/tmpfw
14+
# Mount sources configuration (external injection)
15+
- ./sources.yaml:/app/sources.yaml:ro
16+
# Optional: Mount custom firmware sources
17+
- ./img:/app/img:ro
18+
# Mount entire /dev for USB access
1419
- /dev:/dev
1520
privileged: true
1621
restart: unless-stopped
1722
environment:
1823
- TZ=Europe/Berlin
24+
- PYTHONUNBUFFERED=1
25+
- WEBFLASHER_HOST=0.0.0.0
26+
- WEBFLASHER_PORT=8000
1927
- WEBUI_TITLE=My Custom ESP Flasher
2028
- WEBUI_THEME=dark
2129
healthcheck:

0 commit comments

Comments
 (0)