YLL is a powerful, lightweight URL shortener built with Ruby on Rails. Create and manage shortened URLs with advanced features like expiration dates and password protection.
- Short Links: Generate unique 8-character codes for any URL
- Expiration Control: Set optional expiration times for temporary links
- Security: Password-protect links with HTTP Basic Authentication
- Analytics: Track clicks for each shortened URL
- API Support: Full JSON API for programmatic access
- Ruby 3.0+
- Rails 8.0+
- PostgreSQL (recommended)
# Clone the repository git clone https://github.com/davidesantangelo/yll.git # Navigate to the project directory cd yll # Install dependencies bundle install # Set up the database rails db:create rails db:migrate # Start the server rails server
Create a .env file in the root directory with the following variables:
DATABASE_URL=postgres://username:password@localhost/yll_development
HOST_URL=http://localhost:3000
Visit http://localhost:3000 and use the web form to create a new shortened link.
curl -X POST "http://localhost:3000/api/v1/links" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "password": "optional_password", "expires_at": "2025-12-31T23:59:59Z" }'
Simply visit the generated short URL:
http://localhost:3000/r/{code}
When a link is password-protected, the browser will prompt for credentials:
- Username: The short code
- Password: The password you set when creating the link
Via cURL:
curl -u "{code}:{password}" http://localhost:3000/r/{code}POST /api/v1/links
Request Body:
{
"url": "https://example.com",
"password": "mysecurepassword", // Optional
"expires_at": "2025εΉ΄12ζ31ζ₯T23:59:59Z" // Optional
}Response:
{
"original_url": "https://example.com",
"short_url": "http://localhost:3000/r/Abc12345",
"created_at": "2023εΉ΄01ζ15ζ₯T12:34:56Z",
"expires_at": "2025εΉ΄12ζ31ζ₯T23:59:59Z",
"code": "Abc12345",
"clicks": 0
}GET /api/v1/links/{code}
Response:
{
"original_url": "https://example.com",
"short_url": "http://localhost:3000/r/Abc12345",
"created_at": "2023εΉ΄01ζ15ζ₯T12:34:56Z",
"expires_at": "2025εΉ΄12ζ31ζ₯T23:59:59Z",
"code": "Abc12345",
"clicks": 42
}# Run tests rspec # Run linting rubocop
YLL supports deployment with Kamal, a deployment tool for Ruby on Rails applications that uses Docker and SSH.
- Docker installed locally
- SSH access to your production server
- Docker installed on your production server
- Install the Kamal gem:
gem install kamal
- Initialize Kamal in your project:
kamal init
- Edit the generated
config/deploy.ymlfile:
service: yll image: username/yll registry: username: registry_username password: - KAMAL_REGISTRY_PASSWORD servers: web: hosts: - your-server-ip labels: traefik.http.routers.yll.rule: Host(`yll.yourdomain.com`) env: clear: DATABASE_URL: postgres://username:password@db-host/yll_production RAILS_ENV: production HOST_URL: https://yll.yourdomain.com volumes: - /path/on/host/storage:/rails/storage
# Build and push the Docker image kamal setup # Deploy the application kamal deploy # Check deployment status kamal status # View logs kamal logs # Rollback to previous version kamal rollback
You can set up continuous deployment using GitHub Actions:
- Create
.github/workflows/deploy.yml:
name: Deploy on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.4' - name: Install Kamal run: gem install kamal - name: Deploy run: kamal deploy env: KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
- HTTPS enforcement for destination URLs
- URL validation and availability checking
- Rate limiting to prevent abuse
- Password protection using secure hashing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
YLL uses Rails' has_secure_password for password protection and implements various validations:
- URL format and security validation
- Unique code generation
- Expiration time validation
- URL availability checking
Rate limiting is implemented to prevent abuse, and the application follows Rails best practices for security and performance.