A secure, private image sharing platform built with Symfony 6.4 and PHP 8.2. Share images and albums with specific users while maintaining complete privacy and granular access control.
Image Privacy is Paramount: Images are stored outside the public directory and served through secure, permission-controlled endpoints. No one can access your images without explicit permission.
- β
Secure Storage: Images stored in
/images(not/public/images) - β Permission-Based Access: Every image request is authenticated and authorized
- β Granular Sharing: Share with specific users only (verified users only)
- β Private Comments: Comments visible only to owner and shared users
- β No Public Access: Direct file access is completely blocked
- β CSRF Protection: Enabled on all forms
- β Secure Passwords: Minimum 8 characters, bcrypt hashing
- β Email Verification: Required for new accounts
- β Session Security: Secure cookies with proper configuration
- β Input Validation: All user input validated and sanitized
- β Access Control: Role-based permissions with detailed controls
# config/packages/security.yaml
access_control:
- { path: ^/dashboard, roles: ROLE_USER }
- { path: ^/images/upload, roles: ROLE_USER }
- { path: ^/share, roles: ROLE_USER }
- { path: ^/secure-image, roles: ROLE_USER }// Secure file constraints
new File([
'maxSize' => '10M',
'mimeTypes' => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
'mimeTypesMessage' => 'Please upload a valid image'
])// Only share with verified users
if ($user && $user !== $this->getUser() && $user->isVerified()) {
// Sharing logic here
}The application uses a flexible environment configuration system:
.env- Main application configuration (at project root).env.local- Local overrides (created by setup scripts).docker/.env.docker- Docker development customizations (ports, container names, resource limits)
- Main Configuration:
.envcontains default application settings - Local Overrides:
.env.localcontains your local customizations - Docker Customization:
.docker/.env.dockercontains Docker-specific settings (optional) - Automatic Loading: Docker Compose automatically loads
.env.dockerfor development customizations
This allows the same application to run both locally and in Docker with appropriate configurations.
- Docker and Docker Compose
- Git
# Clone the repository
git clone <your-repo-url>
cd image-share
# Run automated setup
cd .docker
./setup.sh # Linux/Mac
# OR
setup.bat # Windows
# That's it! Your application is ready# Start Docker services
cd .docker
docker-compose up -d
# Copy and configure environment (if not already done)
cp ../.env ../.env.local
# Docker will automatically load .env.docker for port configurations
# Install dependencies
docker-compose exec php composer install
# Create database and run migrations
docker-compose exec php php bin/console doctrine:database:create --if-not-exists
docker-compose exec php php bin/console doctrine:migrations:migrate --no-interaction
# Set permissions
docker-compose exec php chmod -R 777 /var/www/html/var /var/www/html/imagesFor comprehensive documentation, development guides, and technical details, see the .docs/ folder:
- Frontend Development - Vue.js setup, development workflow, and component guide
- Migration Tasks - Twig to Vue.js migration roadmap
- Project Setup - Original project configuration and setup
- Profile System - User profile system documentation
- Sharing Improvements - Image sharing system enhancements
- Documentation Index - Complete documentation overview
No Node.js installation required! The project includes a dedicated Docker container for frontend development:
- Hot Reload: Changes automatically refresh in the browser
- Helper Scripts: Simple commands for common tasks
- Clean Environment: No Node.js pollution on your main machine
- Consistent Setup: Same environment across all team members
Quick Start:
cd .docker
docker-compose up -d # Start all services
./frontend.sh dev # Start frontend dev server (Linux/Mac)
# OR
frontend.bat dev # Start frontend dev server (Windows)Access your Vue.js app at: http://localhost:5173
After setup, access your application at:
- π Application: http://localhost:8080
- ποΈ Database Admin: http://localhost:8082
- Username:
imageshare_user - Password:
imageshare_pass
- Username:
- π§ Email Testing: http://localhost:8026
Login with the pre-created admin account:
- Email:
admin@imageshare.com - Password:
admin123 - Username:
admin
- Upload Images: Support for JPEG, PNG, GIF, WebP (max 100MB)
- Organize Albums: Create public or private albums
- Image Metadata: Title, description, and tags
- Secure Storage: Images stored outside public access
- User-Based Sharing: Share images with specific users only
- Album Sharing: Share entire albums with granular permissions
- Access Control: Owners control who can view their content
- Permission Management: Add/remove access for individual users
- Contextual Discussions: Comment on shared images
- Privacy First: Comments visible only to owner and shared user
- Threaded Conversations: Maintain discussion history
- Secure Communication: No cross-user comment visibility
- Registration: Email verification system
- Authentication: Secure login with role-based access
- Profile Management: User profiles and settings
- Admin Panel: EasyAdmin interface for administration
- Docker Ready: Complete containerized environment
- Database: MariaDB with Doctrine ORM
- Email: Mailpit for development email testing
- Security: Symfony Security component with custom authenticators
- File Upload: VichUploaderBundle for secure file handling
π imageshare_db
βββ π€ user (id, email, username, password, roles, is_verified)
βββ π album (id, user_id, name, description, is_public)
βββ πΌοΈ image (id, user_id, album_id, title, description, image_name)
βββ π share (id, image_id, album_id, shared_by_id, shared_with_id, message)
βββ π¬ comment (id, image_id, share_id, author_id, content)- Image Upload: Stored in secure
/imagesdirectory - Access Request: All image requests go through
/secure-image/{id} - Permission Check: Controller verifies user has access rights
- Serve Image: Only authorized users can view the image
- No Direct Access: Direct file URLs return 403 Forbidden
- Visit http://localhost:8080
- Register a new account or login with admin credentials
- Email verification required for new accounts
- Click "Upload Image" from dashboard
- Select image file (JPEG, PNG, GIF, WebP)
- Add title, description, and optional album
- Upload with secure storage
- Navigate to "My Albums"
- Click "Create Album"
- Set name, description, and privacy level
- Add images to organize your collection
- Go to image or album view
- Click "Share" button
- Enter usernames (comma-separated)
- Add optional message
- Recipients get access notification
- View "My Shares" to see shared content
- Manage who has access to your images
- Remove access for specific users
- Monitor sharing activity
image-share/
βββ .docker/ # Docker configuration
β βββ docker-compose.yml # Multi-service setup
β βββ Dockerfile.php # PHP container
β βββ setup.sh # Linux/Mac setup script
β βββ setup.bat # Windows setup script
βββ config/ # Symfony configuration
βββ public/ # Web accessible files
βββ src/ # Application source code
β βββ Controller/ # Route controllers
β βββ Entity/ # Doctrine entities
β βββ Form/ # Form classes
β βββ Repository/ # Data access layer
β βββ Security/ # Authentication & authorization
β βββ Migrations/ # Database migrations
βββ templates/ # Twig templates
βββ images/ # Secure image storage (auto-created)
βββ vendor/ # Composer dependencies
HomeController- Landing pageSecurityController- Login/logoutRegistrationController- User registrationDashboardController- User dashboardImageController- Image managementAlbumController- Album managementShareController- Sharing functionalityCommentController- Comment systemImageServeController- Secure image serving
User- User accounts and authenticationImage- Image metadata and file handlingAlbum- Image collectionsShare- Sharing relationshipsComment- Private comments
// Before: Public access
GET /public/images/photo.jpg // β Anyone can access
// After: Secure access
GET /secure-image/123 // β
Permission required- Owner Access: Users can always access their own content
- Shared Access: Users can access specifically shared content
- Public Access: Public albums are accessible to all users
- Denied Access: All other requests are blocked
- Base:
php:8.2-apache - Extensions: pdo_mysql, mbstring, gd, zip
- Tools: Composer, Symfony CLI
- Port: 8080
- Version: 10.11
- Database: imageshare_db
- Port: 3306
- Persistent: Data stored in Docker volumes
- Interface: Web-based database management
- Port: 8081
- Access: Connects to MariaDB container
- Purpose: Email testing and debugging
- Ports: 8025 (web), 1025 (SMTP)
- Interface: Modern web UI for email testing
# Check if MariaDB is running
docker-compose ps
# View database logs
docker-compose logs mariadb
# Reset database
docker-compose exec mariadb mysql -u root -p -e "DROP DATABASE imageshare_db; CREATE DATABASE imageshare_db;"
docker-compose exec php php bin/console doctrine:migrations:migrate# Fix file permissions
docker-compose exec php chown -R www-data:www-data /var/www/html
docker-compose exec php chmod -R 777 /var/www/html/var /var/www/html/images- Check if images directory exists:
docker-compose exec php ls -la /var/www/html/images - Verify image permissions:
docker-compose exec php ls -la /var/www/html/images/ - Check web server logs:
docker-compose logs php
- Visit Mailpit: http://localhost:8025
- Check if Mailpit container is running
- Verify MAILER_DSN in
.env.local
# View all logs
docker-compose logs -f
# Access PHP container
docker-compose exec php bash
# Clear Symfony cache
docker-compose exec php php bin/console cache:clear
# View database
docker-compose exec mariadb mysql -u imageshare_user -p imageshare_db
# Restart services
docker-compose restart
# Stop all services
docker-compose down
# Remove all data (including database)
docker-compose down -v- Follow PSR-12 coding standards
- Use Symfony best practices
- Document complex logic with comments
- Use type hints for all methods
- All user input is validated and sanitized
- CSRF protection enabled on all forms
- Passwords hashed with bcrypt
- Session security with secure cookies
- Image access controlled by business logic
- Database indexes on frequently queried fields
- Image caching with ETags and Last-Modified headers
- Lazy loading for related entities
- Query optimization in repositories
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
If you encounter issues:
- Check the troubleshooting section above
- Review Docker logs:
docker-compose logs -f - Check Symfony logs:
docker-compose exec php tail -f var/log/dev.log - Create an issue with detailed information
ImageShare - Because your memories deserve privacy and security! ππΈ