Skip to content

Getting Started

This guide will help you deploy LynkVault on your infrastructure.

Prerequisites

Before deploying, ensure you have:

For Docker Deployment

  • Docker 20.10 or higher
  • Docker Compose 2.0 or higher
  • External MySQL 8.4+ database OR use the included MySQL container

For Kubernetes Deployment

  • Kubernetes cluster 1.20 or higher
  • kubectl configured and working
  • Traefik ingress controller (or modify configs for your ingress)
  • External MySQL 8.4+ database

System Resources

Minimum:

  • 1 CPU core
  • 1 GB RAM
  • 10 GB storage

Recommended:

  • 2+ CPU cores
  • 2+ GB RAM
  • 20+ GB SSD storage

Environment Variables

Create a .env file with the following required variables:

# Database Connection
DATABASE_URL="mysql://user:password@host:3306/lynkvault"

# Application URL
APP_URL=https://links.yourdomain.com

# Authentication Secret (generate with: openssl rand -base64 32)
AUTH_SECRET=your_random_32_character_secret

# Trusted Origins (comma-separated)
AUTH_TRUSTED_ORIGINS=https://links.yourdomain.com

# Optional: Sentry Error Tracking
SENTRY_ENABLED=true

Security

Always generate secure random values for AUTH_SECRET:

openssl rand -base64 32

Deployment Methods

Choose your preferred deployment method:

Docker Compose Deployment

The easiest way to deploy LynkVault.

1. Clone the Repository

git clone https://gitlab.beantech.uk/my-projects/link-shortener.git
cd link-shortener

2. Configure Environment

cp .env.example .env

Edit .env with your configuration:

DATABASE_URL="mysql://lynkvaultuser:lynkvaultpass@mysql:3306/lynkvaultdb"
APP_URL=https://links.yourdomain.com
AUTH_SECRET=$(openssl rand -base64 32)
AUTH_TRUSTED_ORIGINS=https://links.yourdomain.com

3. Deploy

For local testing:

docker compose -f docker-compose.local.yml up

For production:

Create docker-compose.prod.yml:

services:
  lynkvault:
    image: beenhamo/lynkvault:latest
    container_name: lynkvault
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    env_file:
      - .env
    depends_on:
      mysql:
        condition: service_healthy
    networks:
      - lynkvault

  mysql:
    image: mysql:8.4.0-oraclelinux8
    container_name: lynkvault-mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - lynkvault
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 10s
      retries: 10

networks:
  lynkvault:
    driver: bridge

volumes:
  mysql_data:

Then deploy:

docker compose -f docker-compose.prod.yml up -d

4. Access Application

Visit http://localhost:3000 or your configured domain.

5. Set Up Reverse Proxy (Production)

For production deployments, use a reverse proxy with SSL:

Nginx example:

server {
    listen 443 ssl http2;
    server_name links.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Kubernetes Deployment

For production-scale deployments with autoscaling.

1. Create Namespace

# namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: lynkvault
kubectl apply -f namespace.yml

2. Create Secrets

kubectl create secret generic lynkvault-secrets \
  --from-literal=auth-secret=$(openssl rand -base64 32) \
  --from-literal=database-url='mysql://user:password@mysql-host:3306/lynkvault' \
  --namespace=lynkvault

3. Create Deployment

# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lynkvault
  namespace: lynkvault
spec:
  replicas: 2
  selector:
    matchLabels:
      app: lynkvault
  template:
    metadata:
      labels:
        app: lynkvault
    spec:
      containers:
        - name: lynkvault
          image: beenhamo/lynkvault:latest
          ports:
            - containerPort: 3000
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: lynkvault-secrets
                  key: database-url
            - name: AUTH_SECRET
              valueFrom:
                secretKeyRef:
                  name: lynkvault-secrets
                  key: auth-secret
            - name: APP_URL
              value: "https://links.yourdomain.com"
            - name: AUTH_TRUSTED_ORIGINS
              value: "https://links.yourdomain.com"
          livenessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 5
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"
kubectl apply -f deployment.yml

4. Create Service

# service.yml
apiVersion: v1
kind: Service
metadata:
  name: lynkvault
  namespace: lynkvault
spec:
  type: ClusterIP
  selector:
    app: lynkvault
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
kubectl apply -f service.yml

5. Create Ingress (Traefik)

# ingress.yml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: lynkvault
  namespace: lynkvault
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`links.yourdomain.com`)
      kind: Rule
      services:
        - name: lynkvault
          port: 80
  tls:
    certResolver: letsencrypt
kubectl apply -f ingress.yml

6. Optional: Horizontal Pod Autoscaler

# hpa.yml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: lynkvault-hpa
  namespace: lynkvault
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: lynkvault
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
kubectl apply -f hpa.yml

7. Verify Deployment

# Check pods
kubectl get pods -n lynkvault

# Check service
kubectl get svc -n lynkvault

# View logs
kubectl logs -n lynkvault deployment/lynkvault -f

Database Setup

LynkVault requires MySQL 8.4 or higher.

Using Docker MySQL (included in compose files)

The Docker Compose files include a MySQL container that's ready to use.

Using External MySQL

  1. Create a database:
CREATE DATABASE lynkvault CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. Create a user:
CREATE USER 'lynkvault'@'%' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON lynkvault.* TO 'lynkvault'@'%';
FLUSH PRIVILEGES;
  1. Update DATABASE_URL in your environment:
DATABASE_URL="mysql://lynkvault:secure_password@your-mysql-host:3306/lynkvault"

First Run

On first deployment, LynkVault will automatically:

  1. Run database migrations to create all required tables
  2. Set up the authentication system
  3. Start the web server on port 3000

You can then access the application and create your first user account.

Troubleshooting

Application won't start

  • Check logs: docker compose logs lynkvault or kubectl logs -n lynkvault deployment/lynkvault
  • Verify DATABASE_URL is correct
  • Ensure MySQL is accessible and running

Database connection failed

  • Test database connection manually
  • Check firewall rules
  • Verify credentials in DATABASE_URL

Port already in use

  • Change the port mapping in docker-compose.yml:
    ports:
        - '3001:3000' # Use port 3001 instead
    

Cannot access application

  • Verify the service is running
  • Check firewall rules allow access to port 3000
  • For production, ensure reverse proxy is configured correctly

Support

Need help?