Introduction

Fluxend uses Docker containers to create a consistent and predictable environment. There are four containers required to run the application effectively:

  • fluxend_api: The backend container.
  • fluxend_frontend: The frontend container.
  • fluxend_database: The PostgreSQL database container.
  • traefik: The Traefik container responsible for routing traffic to the right service.

The easiest way to deploy Fluxend is to stick with the setup we’ve already created for you. This setup takes care of building the required binaries and running the application in its natural state without unnecessary manual steps.

To get started:

  1. Configure your .env variables and ensure BASE_DOMAIN is set correctly.
  2. Run: make build

Workflow

You can also take a look at our example workflow. We’re using this to deploy to our demo server directly from GitHub. It’s not perfect and will be improved in the coming days, but it should give you a good starting point and ideas on how deployment can be tackled in your own setup.

You can view it here or copy it from below:

name: Deploy Fluxend Application

on:
  push:
    branches: [ main ]
    paths-ignore:
      - 'README.md'
      - 'docs/**'
      - '*.md'
      - '.gitignore'
      - 'LICENSE'

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.23.4'

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'yarn'
          cache-dependency-path: 'web/yarn.lock'

      - name: Build Go binary
        run: |
          mkdir -p bin
          CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bin/fluxend cmd/main.go

      - name: Install frontend dependencies
        working-directory: ./web
        run: yarn install --frozen-lockfile

      - name: Build frontend
        working-directory: ./web
        env:
          VITE_FLX_INTERNAL_URL: ${{ secrets.VITE_FLX_INTERNAL_URL }}
          VITE_FLX_API_URL: ${{ secrets.VITE_FLX_API_URL }}
          VITE_FLX_BASE_DOMAIN: ${{ secrets.VITE_FLX_BASE_DOMAIN }}
          VITE_FLX_HTTP_SCHEME: ${{ secrets.VITE_FLX_HTTP_SCHEME }}
        run: yarn build

      - name: Setup SSH
        uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Add server to known hosts
        run: |
          mkdir -p ~/.ssh
          ssh-keyscan -H ${{ secrets.REMOTE_HOST }} >> ~/.ssh/known_hosts

      - name: Deploy to server
        run: |
          # Prepare backups on server
          ssh ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }} "\
            mkdir -p ${{ secrets.REMOTE_PATH }}/backups && \
            mkdir -p ${{ secrets.REMOTE_PATH }}/web/backups && \
            if [ -f ${{ secrets.REMOTE_PATH }}/bin/fluxend ]; then \
              mv ${{ secrets.REMOTE_PATH }}/bin/fluxend ${{ secrets.REMOTE_PATH }}/backups/fluxend_$(date +%Y%m%d%H%M%S); \
            fi && \
            if [ -d ${{ secrets.REMOTE_PATH }}/web/build ]; then \
              mv ${{ secrets.REMOTE_PATH }}/web/build ${{ secrets.REMOTE_PATH }}/backups/build_$(date +%Y%m%d%H%M%S); \
            fi"

          # Upload backend binary
          scp bin/fluxend ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }}:${{ secrets.REMOTE_PATH }}/bin/

          # Upload frontend build
          scp -r web/build ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }}:${{ secrets.REMOTE_PATH }}/web/

          # Restart containers
          ssh ${{ secrets.REMOTE_USER }}@${{ secrets.REMOTE_HOST }} "\
            cd ${{ secrets.REMOTE_PATH }} && \
            make restart.app" 
      

      - name: Deployment complete
        run: echo "✅ Deployment complete to ${{ secrets.REMOTE_HOST }}"