Deploying open-source projects on Upsun: Snipe-IT as an example
Deploying open-source projects on cloud platforms is not as easy as it seems, especially when you want to customize the application while staying current with upstream updates. The fork-and-deploy approach offers the perfect balance: you get full control over your deployment while maintaining the ability to pull in security patches and new features from the original project.
This guide demonstrates how to deploy any GitHub-hosted open-source project on Upsun using Snipe-IT (an IT asset management system built with Laravel) as our example. The principles and techniques apply to most open-source web applications, regardless of their technology stack.
What you’ll learn
- Fork and configure open-source projects for Upsun deployment
- Adapt application configuration for cloud deployment
- Manage environment variables and service dependencies
- Keep your fork synchronized with upstream changes
- Deploy production-ready open-source applications
Prerequisites
Before starting, ensure you have:
- An Upsun account with an active project
- A GitHub account
- Basic familiarity with Git and command line operations
- Upsun CLI installed locally
Forking the target repository
Start by creating your own fork of the open-source project you want to deploy. This gives you full control over the codebase while maintaining the ability to pull updates from the original project.
Using Snipe-IT as our example:
- Navigate to the Snipe-IT repository on GitHub
- Click the Fork button in the top-right corner
- Choose your GitHub account as the destination
- Wait for GitHub to create your fork
Once forked, clone your repository locally:
git clone https://github.com/YOUR_USERNAME/snipe-it.git
cd snipe-it
For other projects: Replace the repository URL with your target open-source project. The forking process remains identical across all GitHub repositories.
Adding Upsun configuration
Every application needs specific configuration to run on Upsun. We’ll create the necessary configuration files to define our application, services, and deployment process.
The configuration approach varies by technology stack, but the core concepts remain the same. Here’s how to configure a Laravel application (Snipe-IT), with notes on adapting for other frameworks.
Create the Upsun configuration
Create the .upsun/config.yaml
file in your repository root. This example shows a Laravel/PHP configuration, but adapt the runtime, extensions, and build process for your specific technology stack:
applications:
snipeit:
type: php:8.2
source:
root: "/"
runtime:
extensions:
- redis
- pdo_mysql
- gd
- ldap
- zip
- bcmath
relationships:
database: "database:mariadb"
cache: "cache:redis"
web:
locations:
"/":
root: "public"
passthru: "/index.php"
index:
- "index.php"
expires: -1
scripts: true
allow: false
rules:
\.php$:
allow: true
"/storage":
root: "storage/app/public"
expires: 1y
scripts: false
allow: true
mounts:
"storage/app":
source: storage
source_path: app
"storage/logs":
source: storage
source_path: logs
"storage/framework/cache":
source: storage
source_path: cache
"storage/framework/sessions":
source: storage
source_path: sessions
"storage/framework/views":
source: storage
source_path: views
"bootstrap/cache":
source: storage
source_path: bootstrap
hooks:
build: |
set -e
composer install --no-dev --optimize-autoloader
npm ci
npm run build
deploy: |
set -e
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan migrate --force
php artisan storage:link
services:
database:
type: mariadb:11.8
cache:
type: redis-persistent:7.0
routes:
"https://www.{default}/":
type: redirect
to: "https://{default}/"
"https://{default}/":
type: upstream
upstream: "snipeit:http"
Key configuration concepts:
- Runtime: Specify your application’s language and version (php:8.2, node:18, python:3.11, etc.)
- Extensions: Add required language extensions for your application
- Services: Define databases, caches, and other dependencies
- Build/Deploy hooks: Commands to build assets and initialize the application
- Mounts: Writable directories for user uploads, logs, and cache files
Create environment configuration
Create a .environment
file to map Upsun service variables to your application’s expected format. This example shows Laravel environment mapping:
# Database configuration
export DB_CONNECTION="mysql"
export DB_HOST="$DATABASE_HOST"
export DB_PORT="$DATABASE_PORT"
export DB_DATABASE="$DATABASE_PATH"
export DB_USERNAME="$DATABASE_USERNAME"
export DB_PASSWORD="$DATABASE_PASSWORD"
# Cache configuration
export CACHE_DRIVER="redis"
export REDIS_HOST="$CACHE_HOST"
export REDIS_PORT="$CACHE_PORT"
export REDIS_PASSWORD="$CACHE_PASSWORD"
export REDIS_URL="redis://${CACHE_HOST}:${CACHE_PORT}"
# Session configuration
export SESSION_DRIVER="redis"
export SESSION_CONNECTION="default"
# Queue configuration (optional)
export QUEUE_CONNECTION="redis"
# Email configuration
export MAIL_DRIVER="smtp"
export MAIL_HOST="$PLATFORM_SMTP_HOST"
export MAIL_PORT="25"
export MAIL_ENCRYPTION=""
For other frameworks:
- Django: Map to
DATABASE_URL
,REDIS_URL
, etc. - Node.js/Express: Set
DATABASE_URL
,REDIS_URL
,PORT
, etc. - Rails: Configure
DATABASE_URL
,REDIS_URL
,RAILS_ENV
, etc. - WordPress (Bedrock): Map to
DB_HOST
,DB_USER
,DB_PASSWORD
,WP_CACHE_KEY_SALT
, etc.
Commit the configuration
Add and commit your new configuration files:
git add .upsun/config.yaml .environment
git commit -m "Add Upsun deployment configuration"
git push origin master
Note: Most projects use main
instead of master
as the default branch. Adjust accordingly.
Creating your Upsun project
Now create a new Upsun project and connect it to your GitHub repository.
Using the Upsun Console
- Log in to the Upsun Console
- Click Create Project
- Choose Import from GitHub
- Select your forked Snipe-IT repository
- Choose your preferred region (select green regions for extra discounts)
- Configure your project settings:
- Project name: Give your project a descriptive name
- Production branch:
master
ormain
(depending on your repository) - Build and deploy immediately: Check this option
Using the CLI (Alternative)
Alternatively, create the project using the Upsun CLI:
# From your local project directory
upsun login
upsun project:create --title="Snipe-It" --region=us-3.platform.sh --default-branch=master
--default-branch=master
flag as the Snipe-IT GitHub project still uses master
instead of the new default main
.Configuring environment variables
Most open-source applications require environment variables for proper operation. The specific variables depend on your application, but common categories include app configuration, database connections, API keys, and feature flags.
Here are examples for Snipe-IT (Laravel), with notes on what to adapt for other applications:
Generating application secrets
Many applications require unique keys or secrets. For Laravel applications like Snipe-IT, generate the APP_KEY locally:
# Clone locally and generate key
composer install
cp .env.example .env
php artisan key:generate --show
Use the generated key in your APP_KEY
variable (see <ARTISAN-KEY>
below).
For other frameworks:
- Django: Generate
SECRET_KEY
withpython -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
- Node.js: Generate random strings for session secrets using crypto libraries
- Rails: Use
rails secret
to generateSECRET_KEY_BASE
Essential variables
Set these variables at the project level:
upsun variable:create --level project --prefix env --name APP_NAME --value="Snipe-IT"
upsun variable:create --level project --prefix env --sensitive true --name APP_KEY --value="<ARTISAN-KEY>"
upsun variable:create --level environment --environment master --prefix env --name APP_ENV --value="production"
upsun variable:create --level environment --environment master --prefix env --name APP_DEBUG --value="false"
upsun variable:create --level environment --environment master --prefix env --name LOG_LEVEL --value="warning"
# File upload settings
upsun variable:create --level project --prefix env --name PRIVATE_FILESYSTEM_DISK --value="local"
upsun variable:create --level project --prefix env --name PUBLIC_FILESYSTEM_DISK --value="local"
# Email settings
upsun variable:create --level project --prefix env --name MAIL_FROM_ADDR --value="noreply@yourdomain.com"
upsun variable:create --level project --prefix env --name MAIL_FROM_NAME --value="Snipe-IT"
First deployment
If you are using the GitHub integration, Upsun will automatically trigger deployments based on your GitHub repository events. If not, you can start your first deployment:
- Via Console: Navigate to your project and click Deploy
- Via Git: Push changes to your master branch
- Via CLI: Use
upsun redeploy
Upsun will:
- Build your application with the appropriate package manager
- Compile frontend assets (if configured)
- Run database migrations and initialization scripts
- Configure services (databases, caches, etc.)
- Generate SSL certificates
The deployment typically takes 2 to 5 minutes depending on your application size. Monitor progress in the Upsun Console or with:
upsun activity:list
Accessing your deployment
Once deployed, access your application through the provided URL. Most open-source applications require initial setup:
For Snipe-IT:
- Create your admin account
- Configure company settings
- Set up asset categories and models
- Configure LDAP (if needed)
- Customize appearance and branding
For other applications: Check the project’s documentation for first-run setup instructions. Common steps include creating admin accounts, running database seeds, or configuring integrations.
Adding a custom domain
For production use, add your custom domain:
- In the Upsun Console, go to Domains
- Click Add Domain
- Enter your domain name
- Configure DNS with the provided CNAME record
- Wait for SSL certificate provisioning
Keeping your fork updated
Open-source projects receive regular updates for security patches, bug fixes, and new features. Keep your fork synchronized to benefit from these improvements:
Setting up upstream remote
# Add the original repository as upstream (replace with your project's URL)
git remote add upstream https://github.com/snipe/snipe-it.git
# Verify remotes
git remote -v
Syncing updates
Regularly sync with upstream changes. Thanks to Upsun, you can preview and test these updates to avoid any issue with breaking changes:
# Fetch latest changes from upstream
git fetch upstream
# Switch to your master branch
git checkout -b test-ugrade
# Merge upstream changes
git merge upstream/master
# Push updates on a new Upsun preview environment:
git push upsun test-upgrade
# or with the GitHub integration:
git push origin test-upgrade
Handling conflicts
If you’ve customized the application, you may encounter merge conflicts during sync:
- Review conflicts: Use
git status
to identify conflicted files - Resolve manually: Edit files to resolve conflicts
- Test changes: Ensure functionality remains intact
- Commit resolution:
git add .
andgit commit
Automated sync with GitHub Actions
Consider automating upstream sync with GitHub Actions:
name: Sync Upstream
on:
schedule:
- cron: '0 2 * * 1' # Weekly on Monday at 2 AM
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Sync upstream changes
run: |
git remote add upstream https://github.com/ORIGINAL-OWNER/PROJECT-NAME.git
git fetch upstream
git merge upstream/master
git push origin master
Getting help
- Check your project’s official documentation
- Review Upsun documentation for platform-specific issues
- Search the project’s GitHub issues for similar problems
- Join project-specific community forums or the Upsun Discord server
- Check framework-specific resources (Laravel, Django, Rails, etc.)
Conclusion
You now have your open-source application running on Upsun with a robust deployment pipeline. Your setup includes:
- Production-ready services (database, cache, etc.)
- SSL certificates and custom domain support
- Automated upstream synchronization strategy
- Scalable infrastructure that grows with your needs
This fork-and-deploy approach provides the perfect balance between customization control and staying current with upstream improvements. You can modify the application to fit your specific needs while easily pulling in security patches and new features from the original project.