Docker Deployment
This guide covers running Task Fiend with Docker, which provides a self-contained environment with Nginx and PHP-FPM.
Prerequisites
- Docker installed
- Docker Compose (comes with Docker Desktop; install separately on Linux)
Quick start
1. Create environment file
cp .env.example .env
Edit .env and set at minimum:
APP_KEY=base64:your-32-character-random-key-here # or run: php artisan key:generate
APP_ENV=production
APP_DEBUG=false
APP_PORT=8000
2. Build and start
docker compose up -d --build
(Use docker-compose instead of docker compose for Docker V1.)
3. Initialize the database and create your first user
docker compose exec app php artisan migrate --force
docker compose exec app php artisan user:create admin@example.com "Admin User" yourpassword
4. Open the app
Navigate to http://localhost:8000 and log in.
Common Docker commands
# Start/stop
docker compose up -d
docker compose down
# View logs
docker compose logs -f
docker compose logs -f app # PHP only
docker compose logs -f nginx # Nginx only
# Run artisan commands
docker compose exec app php artisan <command>
# Get a shell inside the container
docker compose exec app bash
User and API key management
docker compose exec app php artisan user:create user@example.com "Name" password123
docker compose exec app php artisan user:toggle user@example.com
docker compose exec app php artisan apikey:create user@example.com
docker compose exec app php artisan apikey:invalidate tfk_xxxxx
Production configuration
Recommended .env settings for production:
APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:your-generated-key-here
APP_URL=https://yourdomain.com
APP_PORT=8000
DB_CONNECTION=sqlite
DB_DATABASE=/var/www/html/database/database.sqlite
SESSION_DRIVER=file
CACHE_STORE=file
Persistent data
The database file lives at ./database/database.sqlite on your host and is mounted as a Docker volume. It persists when containers are recreated.
To back it up:
cp database/database.sqlite database/database.sqlite.backup
Using a reverse proxy
If you're putting Task Fiend behind Caddy, Traefik, or another Nginx instance:
-
Bind only to localhost in
docker-compose.yml: ```yaml ports:- "127.0.0.1:8000:80" ```
-
Point your reverse proxy at
http://localhost:8000.
Example Caddy config:
yourdomain.com {
reverse_proxy localhost:8000
}
Architecture
Two containers:
| Container | Role |
|---|---|
| app | PHP 8.2 FPM — runs Laravel, handles artisan commands |
| nginx | Alpine Nginx — serves static files, proxies PHP requests to app |
Both communicate over a Docker network called task_fiend.
Troubleshooting
Permission errors
docker compose exec app chown -R www-data:www-data /var/www/html/storage
docker compose exec app chown -R www-data:www-data /var/www/html/database
docker compose exec app chmod -R 775 /var/www/html/storage
docker compose exec app chmod -R 775 /var/www/html/database
500 Internal Server Error
- Check logs:
docker compose logs nginxanddocker compose logs app - Confirm
APP_KEYis set in.env - Clear config cache:
docker compose exec app php artisan config:clear
Database issues
# Verify the file exists
docker compose exec app ls -la /var/www/html/database/
# Run migrations if needed
docker compose exec app php artisan migrate --force
Port conflict
Change APP_PORT in .env then restart:
docker compose down && docker compose up -d
Rebuilding after changes
docker compose down
docker compose build --no-cache
docker compose up -d