Blink

Easy-to-host, SSO-integrated, CDN-powered link shortener (+decoupled analytics) for teams.

Directory Structure

    • .env
    • docker-compose.yml

docker-compose.yml

version: '3.3'
 
services:
  blink:
    image: ghcr.io/janejeon/blink:latest
    container_name: blink
    env_file:
      - .env
    depends_on:
      - postgres_blink
      - redis_blink
    networks:
      - blink_net
    ports:
      - 3000:3000
    # The frontend can be accessed on this port under the /app folder, eg: if your BASE_URL is test.com, the frontend can be accessed via test.com/app
    # You can use a reverse proxy to configure the /app directory to a different port.
    # You can change the port as well using the above string and the PORT environment variable.
  postgres_blink:
    container_name: postgres_blink
    image: postgres:14-alpine
    ports:
      - 5432:5432
    environment:
      # keep this in sync w/ DATABASE_URL in your environment file/variable
      POSTGRES_DB: blink
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - ./postgres_blink:/var/lib/postgresql/data
    networks:
      - blink_net
  redis_blink:
    container_name: redis_blink
    image: redis:7-alpine
    ports:
      - 6379:6379
    networks:
      - blink_net
networks:
  blink_net:
    name: blink_net

.env

#The port the service runs on
PORT=3000
 
#The database details in the format of: dbprovider://dbusername:dbpassword@dbhost/database
DATABASE_URL=postgres://user:password@postgres_blink/blink
 
#Please leave this enabled for this compose
AUTO_MIGRATE=1
 
#Redis URL in the format of redis://redisurl
REDIS_URL=redis://redis_blink
 
#Page that Blink will redirect to if someone visits the root of your BASE_URL, the way that https://bit.ly redirects to https://bitly.com.
HOMEPAGE=
 
#The URL that your links will be served from, eg: https://bit.ly
BASE_URL=
 
SESSION_DURATION=9 hours
 
#Strong randomly generated sequence of characters.
SESSION_SECRET=
 
## Set to true/false to trust proxy according to https://github.com/jshttp/proxy-addr:
## true means taking the leftmost åddress of X-Forwarded-For (XFF);
## false means taking the remote address;
## a string means comma-delimited list of trusted proxy addresses;
## there are 3 pre-configured subnet names:
## - loopback - 127.0.0.1/8, ::1/128
## - linklocal - 169.254.0.0/16, fe80::/10
## - uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7
TRUST_PROXY=loopback,linklocal,uniquelocal
 
## This is a shorter term rate limit, meant to account for "bursty" request patterns
RATE_LIMIT_SHORT_WINDOW=1 min
RATE_LIMIT_SHORT_MAX=100
 
## This is the longer term rate limit, meant to generally limit the abuse of authentication and APIs
RATE_LIMIT_LONG_WINDOW=15 min
RATE_LIMIT_LONG_MAX=200
 
## How long to wait before the backend gives up scraping a link
LINK_TIMEOUT=15 seconds
 
## How long the cache should last for a redirect/301
CACHE_MAX_AGE=10 years
 
#For use with OIDC auth/identity provider, such as Keycloak.
OIDC_CLIENT_ID=
OIDC_ISSUER_BASE_URL=
OIDC_HTTP_TIMEOUT=15 seconds
 
## OAuth2 Config for API access to Blink; disable if you don't use this
OAUTH2_ENABLED=true
OAUTH2_JWT_ALGORITHMS=RS256
OAUTH2_JWT_AUDIENCE=
OAUTH2_JWT_ISSUER=
OAUTH2_JWT_SECRET=
 
### You can either specify a static secret or dynamically load the secret to the JWT token using JWKS.
### Setting OAUTH2_JWT_SECRET will use static secret, otherwise it will use dynamic secrets (recommended).
OAUTH2_JWKS_URI=
OAUTH2_JWKS_HTTP_TIMEOUT=15 seconds
OAUTH2_JWKS_REQUESTS_PER_MINUTE=10
 
## This will determine the default scope assigned to OAuth2 tokens
OAUTH2_DEFAULT_SCOPE=user:create user:read link:*
 
# Frontend config
REACT_APP_BASE_URL=$BASE_URL

Resources

Website: https://docs.blink.rest/

GitHub: https://github.com/JaneJeon/blink

GitHub Container Registry: https://github.com/JaneJeon/blink/pkgs/container/blink

Configuration: https://github.com/JaneJeon/blink/tree/master/deploy/docker-compose