Build Your Mobile App Backend in 15 Minutes
Difficulty: Beginner | Time: ~15 minutes | Target: Mobile developers evaluating Firebase alternatives
This tutorial walks you through setting up a production-ready backend for a mobile app using three open source services on Eyevinn Open Source Cloud:
- PostgreSQL for relational data storage (user profiles, app data)
- Valkey for session caching and real-time key-value storage
- MinIO for file and image storage (S3-compatible)
At the end of this tutorial you will have all three services running and connection strings ready to paste into your iOS or Android app.
Prerequisites
- An Eyevinn Open Source Cloud account. Sign up here for free.
- A Personal or higher plan (running three simultaneous services requires a paid plan)
Step 1: Start a PostgreSQL Instance
PostgreSQL is where your app stores structured data: user profiles, app content, relationships between records.
- Go to app.osaas.io and open the Browse page
- Search for PostgreSQL and click the service card
- Subscribe to the service if you have not already done so
- Click Create instance and fill in the form:
- Name:
myapp-db(or any name you choose) - PostgresUser:
appuser - PostgresPassword: choose a strong password and note it down
- PostgresDb:
appdb - Click Create and wait for the status to show Running (usually under a minute)
- Click on the instance card to expand it and copy the host and port values
Your PostgreSQL connection details will look like this:
Host: <your-tenant>-myapp-db.birme-osc-postgresql.auto.prod.osaas.io
Port: 5432
Database: appdb
User: appuser
Password: <your-password>
Connection string:
postgresql://appuser:<YOUR_PASSWORD>@<YOUR_HOST>:5432/appdb
Step 2: Start a Valkey Instance
Valkey is a Redis-compatible key-value store. Use it for session tokens, caching API responses, and storing short-lived data that does not need to go into the database.
- On the Browse page, search for Valkey and click the service card
- Subscribe to the service if needed
- Click the Service Secrets tab and create a secret for your Valkey password:
- Click Create secret
- Give it a name, for example
valkey-pwd - Enter a strong password as the value
- Click the My valkeys tab and then Create valkey:
- Name:
myapp-cache - Password: select the secret you just created (
{{secrets.valkey-pwd}}) - Click Create and wait for the status to show Running
- Note the IP address and port shown on the instance card once it is running
Your Valkey connection details will look like this:
Host: <IP address shown on the instance card>
Port: <port shown on the instance card>
Password: <the password you stored in the secret>
Connection string (Redis-compatible URL):
redis://:<YOUR_PASSWORD>@<YOUR_IP>:<YOUR_PORT>
Step 3: Start a MinIO Instance
MinIO provides S3-compatible object storage for images, files, and any binary content your app needs to store or serve.
- On the Browse page, search for MinIO and click the service card
- Subscribe to the service if needed
- Click Create objstorage and fill in the form:
- Name:
myapp-storage - RootUser:
approot - RootPassword: choose a strong password and note it down
- Click Create and wait for the status to show Running
- Click on the instance card to see the service URL
Your MinIO endpoint will look like this:
Endpoint: https://<your-tenant>-myapp-storage.minio-minio.auto.prod.osaas.io
AccessKey: approot
SecretKey: <your-root-password>
Create a bucket for your app's files. You can use the MinIO web console at https://<your-tenant>-myapp-storage.minio-minio.auto.prod.osaas.io (log in with your root credentials), or use the AWS CLI:
export AWS_ACCESS_KEY_ID=approot
export AWS_SECRET_ACCESS_KEY=<YOUR_ROOT_PASSWORD>
aws --endpoint-url https://<YOUR_MINIO_ENDPOINT> s3 mb s3://app-files
Step 4: Connect Your Mobile App
Use the connection details from steps 1 to 3 to configure your mobile app. The examples below use placeholder values, replace them with your actual values.
iOS (Swift)
PostgreSQL with PostgresClientKit:
import PostgresClientKit
var configuration = PostgresClientKit.ConnectionConfiguration()
configuration.host = "<YOUR_HOST>"
configuration.port = 5432
configuration.database = "appdb"
configuration.user = "appuser"
configuration.credential = .md5Password(password: "<YOUR_PASSWORD>")
configuration.ssl = true
let connection = try PostgresClientKit.Connection(configuration: configuration)
Valkey / Redis with RediStack:
import RediStack
import NIO
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let client = try RedisConnection.make(
configuration: try .init(
hostname: "<YOUR_IP>",
port: <YOUR_PORT>,
password: "<YOUR_PASSWORD>"
),
boundEventLoop: eventLoopGroup.next()
).wait()
MinIO / S3 with the AWS SDK for Swift:
import AWSS3
// Configure the S3 client with your MinIO endpoint
// Set the endpoint override to your MinIO instance URL
// Use "approot" as the access key and your root password as the secret key
let s3Config = try await S3Client.S3ClientConfiguration(region: "us-east-1")
For MinIO with the AWS Swift SDK, set the custom endpoint to your MinIO instance URL and use
approotas the access key.
Android (Kotlin)
PostgreSQL with JDBC:
import java.sql.DriverManager
val url = "jdbc:postgresql://<YOUR_HOST>:5432/appdb"
val props = java.util.Properties().apply {
setProperty("user", "appuser")
setProperty("password", "<YOUR_PASSWORD>")
setProperty("ssl", "true")
}
val connection = DriverManager.getConnection(url, props)
Run database calls on a background thread (Coroutines or RxJava) to avoid blocking the main thread.
Valkey / Redis with Jedis:
import redis.clients.jedis.Jedis
val jedis = Jedis("<YOUR_IP>", <YOUR_PORT>)
jedis.auth("<YOUR_PASSWORD>")
// Store a session token
jedis.setex("session:user123", 3600, "token-value-here")
// Retrieve it
val token = jedis.get("session:user123")
MinIO / S3 with the AWS SDK for Android:
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.regions.Region
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.S3ClientOptions
val credentials = BasicAWSCredentials("approot", "<YOUR_ROOT_PASSWORD>")
val s3Client = AmazonS3Client(credentials)
s3Client.setRegion(Region.getRegion("us-east-1"))
s3Client.setEndpoint("https://<YOUR_MINIO_ENDPOINT>")
s3Client.setS3ClientOptions(
S3ClientOptions.builder().setPathStyleAccess(true).build()
)
// Upload a file
s3Client.putObject("app-files", "profile/user123.jpg", File("/path/to/image.jpg"))
Step 5: Test the Setup
Before wiring everything into your app, verify that each service is reachable.
Test PostgreSQL
psql "postgresql://appuser:<YOUR_PASSWORD>@<YOUR_HOST>:5432/appdb" -c "SELECT version();"
You should see the PostgreSQL version string. If you get a connection error, double-check the host, port, and password on the instance card in the OSC web console.
Test Valkey
export REDISCLI_AUTH=<YOUR_PASSWORD>
redis-cli -h <YOUR_IP> -p <YOUR_PORT> PING
Expected response: PONG
Test MinIO
export AWS_ACCESS_KEY_ID=approot
export AWS_SECRET_ACCESS_KEY=<YOUR_ROOT_PASSWORD>
aws --endpoint-url https://<YOUR_MINIO_ENDPOINT> s3 ls
You should see the app-files bucket listed.
What You Have Built
You now have a complete backend stack running on open source infrastructure:
| Service | Purpose | Protocol |
|---|---|---|
| PostgreSQL | Relational data storage | JDBC / libpq |
| Valkey | Session cache and key-value store | Redis protocol |
| MinIO | File and image storage | S3 API |
All three services run on Eyevinn Open Source Cloud without any vendor lock-in. You can move them to your own infrastructure at any time because they are standard open source projects.
Next Steps
- Database Backups to schedule automated backups for your PostgreSQL instance
- Working with Secrets to manage credentials securely using the OSC secrets store
- Parameter Store to store and retrieve app configuration at runtime
- Custom Domains to attach your own domain to services