app/.docker/production/README.md

346 lines
9.6 KiB
Markdown
Raw Normal View History

# Dish Planner - Self-Hosted Deployment Guide
This directory contains everything you need to deploy Dish Planner as a self-hosted all-in-one container.
> **Note**: This guide uses an embedded docker-compose configuration (no separate file to download). Simply copy the YAML configuration shown below and save it as `docker-compose.yml`.
## Quick Start
### For End Users (Using Pre-Built Image)
> **Image Versioning**: This guide uses the `:latest` tag for simplicity. For production deployments, consider using a specific version tag (e.g., `:v0.3`) for stability and predictable updates.
1. **Create a docker-compose.yml file:**
Copy the following configuration and save it as `docker-compose.yml`:
```yaml
# ============================================
# Dish Planner - Self-Hosted Deployment
# ============================================
#
# QUICK START:
# 1. Save this file as docker-compose.yml
# 2. (Optional) Edit the environment variables below
# 3. Run: docker compose up -d
# 4. Access your app at http://localhost:3000
#
# IMPORTANT SECURITY NOTES:
# - Database credentials are auto-generated on first run
# - Check the container logs to see generated credentials:
# docker logs dishplanner
# - For production, set a custom APP_URL environment variable
#
# CUSTOMIZATION:
# You can override any environment variable by uncommenting
# and editing the values below, or by creating a .env file.
#
# ============================================
services:
dishplanner:
# Pre-built all-in-one image from Codeberg Container Registry
image: codeberg.org/lvl0/dish-planner:latest
container_name: dishplanner
restart: unless-stopped
# ----------------------------------------
# Port Configuration
# ----------------------------------------
# The application will be accessible on port 3000
# Change the left number to use a different host port
# Example: "8080:80" to access on port 8080
ports:
- "3000:80"
# ----------------------------------------
# Environment Variables
# ----------------------------------------
# Uncomment and customize as needed
environment:
# Application URL (set this to your domain)
- APP_URL=http://localhost:3000
# Application environment (production recommended)
- APP_ENV=production
# Debug mode (set to false in production for security)
- APP_DEBUG=false
# Database configuration
# Note: Credentials are auto-generated on first run if not set
# Check logs for generated credentials: docker logs dishplanner
# - DB_DATABASE=dishplanner
# - DB_USERNAME=dishuser
# - DB_PASSWORD=change-this-secure-password
# Timezone (optional)
# - APP_TIMEZONE=UTC
# ----------------------------------------
# Persistent Data Volumes
# ----------------------------------------
# These volumes ensure data persists across container restarts
volumes:
# MySQL database data
- dishplanner_mysql_data:/var/lib/mysql
# Laravel storage (uploaded files, logs, cache)
- dishplanner_storage:/var/www/backend/storage
# Supervisor logs
- dishplanner_logs:/var/log/supervisor
# ----------------------------------------
# Health Check (optional)
# ----------------------------------------
# Uncomment to enable container health monitoring
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost/api/health"]
# interval: 30s
# timeout: 10s
# retries: 3
# start_period: 60s
# ----------------------------------------
# Named Volumes
# ----------------------------------------
# Docker manages these volumes - data persists even if container is removed
volumes:
dishplanner_mysql_data:
driver: local
dishplanner_storage:
driver: local
dishplanner_logs:
driver: local
# ----------------------------------------
# Network Configuration
# ----------------------------------------
# Uses default bridge network (suitable for single-host deployment)
# For advanced setups, you can define custom networks here
```
2. **Start the application:**
```bash
docker compose up -d
```
3. **View the initialization logs to get your database credentials:**
```bash
docker logs dishplanner
```
Save the auto-generated database credentials shown in the logs!
4. **Access the application:**
Open your browser to `http://localhost:3000`
That's it! The application is now running with:
- MySQL database
- Laravel backend API
- React Router frontend
- Nginx reverse proxy
- Background queue worker
### For DockGE Users
1. In the DockGE web UI, click "Add Stack"
2. Copy the entire YAML configuration from the code block above (starting from `services:` and including all volumes)
3. Paste it into the DockGE compose editor
4. Optionally edit the environment variables
5. Click "Start"
6. View logs to get auto-generated database credentials
## Configuration
### Environment Variables
You can customize the deployment by setting these environment variables in the docker-compose file:
| Variable | Default | Description |
|----------|---------|-------------|
| `APP_URL` | `http://localhost:3000` | The URL where your app is accessible |
| `APP_ENV` | `production` | Environment mode (production/local) |
| `APP_DEBUG` | `false` | Enable debug mode (never use in production!) |
| `DB_DATABASE` | `dishplanner` | Database name |
| `DB_USERNAME` | `dishuser` | Database username |
| `DB_PASSWORD` | Auto-generated | Database password (check logs for generated value) |
### Changing the Port
By default, the app runs on port 3000. To use a different port, edit the `ports` section:
```yaml
ports:
- "8080:80" # This makes the app available on port 8080
```
### Persistent Data
The following data is persisted in Docker volumes:
- **MySQL database** - All your dishes, schedules, and users
- **Laravel storage** - Uploaded files, logs, and cache
- **Supervisor logs** - Application and service logs
Even if you remove the container, this data remains intact.
## Building the Image Yourself
If you prefer to build the image yourself instead of using the pre-built one:
1. **Clone the repository:**
```bash
git clone https://codeberg.org/lvl0/dish-planner.git
cd dish-planner
```
2. **Build the image:**
```bash
docker build -f .docker/production/Dockerfile -t codeberg.org/lvl0/dish-planner:latest .
```
3. **Create a docker-compose.yml file** using the configuration shown in the Quick Start section above (or save the embedded compose config to a file)
4. **Run it:**
```bash
docker compose up -d
```
## Management
### Viewing Logs
```bash
# All logs
docker logs dishplanner
# Follow logs in real-time
docker logs -f dishplanner
# Last 100 lines
docker logs --tail 100 dishplanner
```
### Stopping the Application
```bash
docker compose down
```
### Restarting the Application
```bash
docker compose restart
```
### Updating to a New Version
1. Pull the latest image:
```bash
docker compose pull
```
2. Recreate the container:
```bash
docker compose up -d
```
3. Your data persists in volumes automatically!
## Troubleshooting
### "Cannot connect to database"
Check that MySQL started successfully:
```bash
docker logs dishplanner | grep mysql
```
### "502 Bad Gateway"
One of the services may not have started. Check supervisor logs:
```bash
docker exec dishplanner supervisorctl status
```
### Reset Everything (CAUTION: Deletes all data!)
```bash
docker compose down -v # The -v flag removes volumes
docker compose up -d
```
### Access the Container Shell
```bash
docker exec -it dishplanner bash
```
### Run Laravel Commands
```bash
# Run migrations
docker exec dishplanner php /var/www/backend/artisan migrate
# Create a new user (if needed)
docker exec -it dishplanner php /var/www/backend/artisan tinker
```
## Architecture
This all-in-one container includes:
- **MySQL 8.0** - Database server
- **PHP 8.2-FPM** - Runs the Laravel backend
- **Node.js 20** - Runs the React Router frontend
- **Nginx** - Web server and reverse proxy
- **Supervisord** - Process manager that keeps everything running
All services start automatically and are monitored by supervisord. If any service crashes, it will be automatically restarted.
## Security Recommendations
For production deployments:
1. **Set a strong database password:**
```yaml
environment:
- DB_PASSWORD=your-very-secure-password-here
```
2. **Use HTTPS:** Put the container behind a reverse proxy (Nginx, Caddy, Traefik) with SSL/TLS
3. **Set APP_DEBUG to false:**
```yaml
environment:
- APP_DEBUG=false
```
4. **Keep the image updated:** Regularly pull and deploy new versions
5. **Backup your data:**
```bash
# Backup volumes
docker run --rm -v dishplanner_mysql_data:/data -v $(pwd):/backup ubuntu tar czf /backup/mysql-backup.tar.gz /data
```
## Support
For issues and questions:
- Codeberg Issues: https://codeberg.org/lvl0/dish-planner/issues
- Documentation: https://codeberg.org/lvl0/dish-planner
## What's Inside
The container runs these processes (managed by supervisord):
1. **MySQL** - Database (port 3306, internal only)
2. **PHP-FPM** - Laravel application (port 9000, internal only)
3. **Node.js** - React frontend (port 3000, internal only)
4. **Nginx** - Reverse proxy (port 80, exposed)
5. **Queue Worker** - Background job processor
Only Nginx's port 80 is exposed to the host (mapped to 3000 by default).