Server-Side Rendered Node.js/TypeScript website developed during a backend development internship.
3.0K
A modern self-hosted social media platform built with Node.js, Express, TypeScript, MySQL, and Redis. Features posts with optional images, comments, likes/dislikes, email verification, and a guided setup wizard.
GitHub: https://github.com/OmairSalman/UsersConnectโ
Live Version: https://usersconnect.cloudomair.org/โ
sameSite: none now applies across all auth flows (login, registration, password reset, email verification, email change), completing the mobile support started in v1.0.4Secure (see note below)As of v1.1.0, authentication cookies are always set with the Secure attribute (required by SameSite=None), so the app must be served over HTTPS for sign-in to work.
http://localhost is treated as secure by Chrome/Firefox (so it works), but accessing from a phone over the LAN requires real TLS (e.g. mkcert or a tunnel). See "Why HTTPS is required"โ in the README.docker pull omairsalman/usersconnect:latest
Save as docker-compose.yml:
version: '3.8'
services:
app:
image: omairsalman/usersconnect:latest
ports:
- "3000:3000"
volumes:
- ./config.yaml:/app/config.yaml
- ./logs:/app/logs
environment:
- NODE_ENV=production
- DATABASE_HOST=mysql
- DATABASE_USERNAME=root
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- DATABASE_NAME=usersconnect
- REDIS_HOST=redis
- REDIS_PASSWORD=${REDIS_PASSWORD}
- ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
- REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
depends_on:
- mysql
- redis
restart: unless-stopped
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_DATABASE: usersconnect
volumes:
- mysql_data:/var/lib/mysql
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
mysql_data:
redis_data:
docker-compose up -d
Generate secrets for .env:
openssl rand -base64 16 # For passwords
openssl rand -base64 32 # For JWT secrets
/setup)Done! Your instance is ready to use.
Note: Because authentication now requires HTTPS, access your instance through your HTTPS reverse proxy rather than plain
http://...:3000. See the HTTPS note above.
docker run -d \
-p 3000:3000 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/logs:/app/logs \
-e NODE_ENV=production \
-e DATABASE_HOST=your-mysql-host \
-e DATABASE_USERNAME=root \
-e DATABASE_PASSWORD=yourpassword \
-e DATABASE_NAME=usersconnect \
-e REDIS_HOST=your-redis-host \
-e REDIS_PASSWORD=yourredispassword \
-e ACCESS_TOKEN_SECRET=$(openssl rand -base64 32) \
-e REFRESH_TOKEN_SECRET=$(openssl rand -base64 32) \
omairsalman/usersconnect:latest
Add these environment variables:
-e S3_ACCESS_KEY=your-aws-access-key \
-e S3_SECRET_KEY=your-aws-secret-key \
-e S3_BUCKET_NAME=usersconnect-media \
-e S3_REGION=us-east-1 \
-e SMTP_HOST=smtp.zoho.com \
-e SMTP_PORT=465 \
-e SMTP_SECURE=true \
-e [email protected] \
-e SMTP_PASSWORD=your_smtp_password \
| Environment Variable | YAML Equivalent | Description | Example |
|---|---|---|---|
DATABASE_HOST | database.host | MySQL host | mysql or localhost |
DATABASE_PORT | database.port | MySQL port (optional) | 3306 (default) |
DATABASE_USERNAME | database.username | MySQL user | root |
DATABASE_PASSWORD | database.password | MySQL password | yourpassword |
DATABASE_NAME | database.name | Database name | usersconnect |
REDIS_HOST | redis.host | Redis host | redis or localhost |
REDIS_PORT | redis.port | Redis port (optional) | 6379 (default) |
REDIS_PASSWORD | redis.password | Redis password (optional) | yourredispassword |
ACCESS_TOKEN_SECRET | jwt.accessTokenSecret | JWT access token secret | Generate: openssl rand -base64 32 |
REFRESH_TOKEN_SECRET | jwt.refreshTokenSecret | JWT refresh token secret | Generate: openssl rand -base64 32 |
Image uploads are automatically enabled when these variables are set:
| Environment Variable | YAML Equivalent | Description | Example |
|---|---|---|---|
S3_ACCESS_KEY | s3.accessKey | S3 access key ID | AKIAIOSFODNN7EXAMPLE |
S3_SECRET_KEY | s3.secretKey | S3 secret access key | wJalrXUtnFEMI/... |
S3_BUCKET_NAME | s3.bucketName | S3 bucket name | usersconnect-media |
S3_REGION | s3.region | AWS region | us-east-1 |
S3_ENDPOINT | s3.endpoint | Custom endpoint (for non-AWS S3) | http://minio:9000 |
Email features are automatically enabled when these variables are set:
| Environment Variable | YAML Equivalent | Description | Example |
|---|---|---|---|
SMTP_HOST | smtp.host | SMTP server host | smtp.zoho.com |
SMTP_PORT | smtp.port | SMTP server port | 465 or 587 |
SMTP_SECURE | smtp.secure | Use SSL/TLS | true or false |
SMTP_USER | smtp.user | SMTP username | [email protected] |
SMTP_PASSWORD | smtp.password | SMTP password | your_smtp_password |
CORS is disabled by default. Enable for separate frontend applications:
| Environment Variable | YAML Equivalent | Description | Example |
|---|---|---|---|
CORS_ENABLED | cors.enabled | Enable CORS | true or false |
CORS_ALLOWED_ORIGINS | cors.allowedOrigins | Allowed origins (comma-separated) | http://localhost:4200,https://app.example.com |
CORS_ALLOW_CREDENTIALS | cors.allowCredentials | Allow credentials | true or false |
CORS_ALLOWED_METHODS | cors.allowedMethods | Allowed HTTP methods (comma-separated) | GET,POST,PUT,DELETE |
CORS_ALLOWED_HEADERS | cors.allowedHeaders | Allowed headers (comma-separated) | Content-Type,Authorization |
| Environment Variable | YAML Equivalent | Description | Example |
|---|---|---|---|
LOG_LEVEL | logging.level | Winston log level | info, debug, warn, error |
Logging file location and rotation are configurable via
logging.directory,logging.maxFileSize, andlogging.maxFilesinconfig.yaml. A relativedirectory(the default,logs) resolves under the app working directory (/app/logsin the container); an absolute path is honored as-is.
Configuration Priority: Environment variables always override YAML:
Defaults โ config.yaml โ Environment Variables
Option 1: config.yaml Only (All Configuration)
# config.yaml - Complete example with all options
# Required: Database
database:
host: mysql
port: 3306
username: root
password: yourpassword
name: usersconnect
# Required: Redis
redis:
host: redis
port: 6379
password: yourredispassword # Optional
# Required: JWT
jwt:
accessTokenSecret: your-access-token-secret-here
refreshTokenSecret: your-refresh-token-secret-here
# Optional: S3 Image Uploads (remove if not using)
s3:
accessKey: AKIAIOSFODNN7EXAMPLE
secretKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
bucketName: usersconnect-media
region: us-east-1
endpoint: http://minio:9000 # Only for non-AWS S3
# Optional: SMTP Email (remove if not using)
smtp:
host: smtp.zoho.com
port: 465
secure: true
user: [email protected]
password: your_smtp_password
# Optional: CORS (remove if not using)
cors:
enabled: true
allowedOrigins:
- http://localhost:4200
- https://app.example.com
allowCredentials: true
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders:
- Content-Type
- Authorization
# Optional: Logging
logging:
level: info # debug, info, warn, error
Option 2: Environment Variables Only
environment:
# Required
- NODE_ENV=production
- DATABASE_HOST=mysql
- DATABASE_PORT=3306
- DATABASE_USERNAME=root
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- DATABASE_NAME=usersconnect
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
- ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
- REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
# Optional: S3
- S3_ACCESS_KEY=AKIA...
- S3_SECRET_KEY=${S3_SECRET_KEY}
- S3_BUCKET_NAME=usersconnect-media
- S3_REGION=us-east-1
- S3_ENDPOINT=http://minio:9000
# Optional: SMTP
- SMTP_HOST=smtp.zoho.com
- SMTP_PORT=465
- SMTP_SECURE=true
- [email protected]
- SMTP_PASSWORD=${SMTP_PASSWORD}
# Optional: CORS
- CORS_ENABLED=true
- CORS_ALLOWED_ORIGINS=http://localhost:4200
- CORS_ALLOW_CREDENTIALS=true
- CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE
- CORS_ALLOWED_HEADERS=Content-Type,Authorization
# Optional: Logging
- LOG_LEVEL=info
Option 3: Mixed (Secrets in ENV, Config in YAML)
# docker-compose.yml
volumes:
- ./config.yaml:/app/config.yaml
environment:
# Secrets only
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
- REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
- S3_SECRET_KEY=${S3_SECRET_KEY}
- SMTP_PASSWORD=${SMTP_PASSWORD}
# config.yaml
database:
host: mysql
port: 3306
username: root
name: usersconnect
redis:
host: redis
port: 6379
s3:
accessKey: AKIA...
bucketName: usersconnect-media
region: us-east-1
endpoint: http://minio:9000
smtp:
host: smtp.zoho.com
port: 465
secure: true
user: [email protected]
cors:
enabled: true
allowedOrigins:
- http://localhost:4200
- https://app.example.com
allowCredentials: true
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders:
- Content-Type
- Authorization
logging:
level: info
Works with any S3-compatible storage:
Complete docker-compose with MinIO:
version: '3.8'
services:
app:
image: omairsalman/usersconnect:latest
ports:
- "3000:3000"
volumes:
- ./config.yaml:/app/config.yaml
- ./logs:/app/logs
environment:
- NODE_ENV=production
- DATABASE_HOST=mysql
- DATABASE_USERNAME=root
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- DATABASE_NAME=usersconnect
- REDIS_HOST=redis
- REDIS_PASSWORD=${REDIS_PASSWORD}
- ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
- REFRESH_TOKEN_SECRET=${REFRESH_TOKEN_SECRET}
# MinIO S3
- S3_ACCESS_KEY=minioadmin
- S3_SECRET_KEY=minioadmin
- S3_BUCKET_NAME=usersconnect-media
- S3_REGION=us-east-1
- S3_ENDPOINT=http://minio:9000
depends_on:
- mysql
- redis
- minio
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_DATABASE: usersconnect
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
minio:
image: minio/minio:latest
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
minio-setup:
image: minio/mc:latest
depends_on:
- minio
entrypoint: >
/bin/sh -c "
sleep 5;
mc alias set myminio http://minio:9000 minioadmin minioadmin;
mc mb myminio/usersconnect-media --ignore-existing;
mc anonymous set download myminio/usersconnect-media;
exit 0;
"
volumes:
mysql_data:
redis_data:
minio_data:
MinIO Console: http://localhost:9001 (minioadmin/minioadmin)
When SMTP is configured:
When SMTP is not configured:
Secure/SameSite=None, so the app must be served over HTTPS via a reverse proxy (Nginx/Caddy/Traefik/Nginx Proxy Manager)openssl rand -base64 32Minimum:
Recommended:
The Docker image bundles its own Node.js runtime; a local Node.js install is only needed when building from source.
Secure and browsers reject them over plain HTTPhttp://localhost is treated as secure by Chrome/Firefox; LAN-IP access from a phone needs real TLS)allowCredentials: true and your origin is in allowedOriginsDATABASE_HOST matches your setupREDIS_HOST is correctREDIS_PASSWORD if setlatest - Latest stable release1.1.0 - Current release1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0.0 - Previous releasesPull a specific version:
docker pull omairsalman/usersconnect:1.1.0
# Backup database first
docker exec mysql mysqldump -u root -p usersconnect > backup.sql
# Pull the new image
docker pull omairsalman/usersconnect:latest
# Recreate containers (migrations run automatically)
docker-compose down
docker-compose up -d
# Verify in logs
docker-compose logs app
No breaking changes to data or configuration. Note that v1.1.0 requires the app to be served over HTTPS for authentication โ see the HTTPS note above.
git clone https://github.com/OmairSalman/UsersConnect.git
cd UsersConnect
npm install
npm run build
docker build -t usersconnect:custom .
MIT License - See LICENSEโ
Omair Salman
Initially developed during summer field training at AsalTechโ , with continued development thereafter.
โญ Star on GitHub: https://github.com/OmairSalman/UsersConnectโ
๐ฌ Discussions: https://github.com/OmairSalman/UsersConnect/discussionsโ
๐ Report Issues: https://github.com/OmairSalman/UsersConnect/issuesโ
Latest Release: v1.1.0 ๐
Content type
Image
Digest
sha256:49470edecโฆ
Size
112.3 MB
Last updated
3 months ago
docker pull omairsalman/usersconnect