Tutorial8 min readApril 30, 2025

Install FreeScout with Docker — Complete Guide (2025)

Use Docker to deploy FreeScout with docker-compose. Includes MySQL, NGINX, SSL, and why Docker is perfect for testing and production.

Docker containerizes FreeScout into isolated, reproducible environments. This guide shows you how to deploy FreeScout with docker-compose in under 30 minutes.

Docker is ideal if you:

  • Want to test FreeScout before committing to a full VPS
  • Run multiple applications on one server
  • Need easy scaling and rollbacks
  • Prefer automation over manual configuration

Why Docker?

Pros:

  • ✅ Install in 5 minutes (not 4 hours)
  • ✅ Reproducible — same setup on any machine
  • ✅ Easy scaling — run 2 containers instead of 1
  • ✅ Easy updates — pull new image, restart
  • ✅ Isolation — FreeScout doesn't affect other apps

Cons:

  • ❌ Slightly more resources than bare metal
  • ❌ Steeper learning curve (container concepts)
  • ❌ Logs and debugging require Docker knowledge

Best for: Developers, small teams, testing, or teams already using Docker.


Prerequisites

You need:

  • A VPS or local machine with Linux (Ubuntu 20.04+)
  • Docker installed (apt install docker.io)
  • Docker Compose installed (apt install docker-compose)
  • A domain name (optional, but recommended)
  • 2GB+ RAM for the container

Step 1: Install Docker & Docker Compose

sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose git
sudo usermod -aG docker $USER  # Run Docker without sudo

Verify installation:

docker --version
docker-compose --version

Step 2: Create Docker Compose File

Create a directory for FreeScout:

mkdir -p ~/freescout
cd ~/freescout

Create docker-compose.yml:

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_password_here
      MYSQL_DATABASE: freescout
      MYSQL_USER: freescout
      MYSQL_PASSWORD: freescout_password
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqldump", "--no-data", "-u", "root", "--password=root_password_here", "freescout"]
      interval: 10s
      timeout: 5s
      retries: 5

  freescout:
    image: freescoutapp/freescout:latest
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      APP_URL: http://localhost:8080
      APP_ENV: production
      APP_KEY: base64:change_me_to_a_random_string
      DB_HOST: mysql
      DB_PORT: 3306
      DB_DATABASE: freescout
      DB_USERNAME: freescout
      DB_PASSWORD: freescout_password
      MAIL_DRIVER: smtp
      MAIL_HOST: smtp.sendgrid.net
      MAIL_PORT: 587
      MAIL_USERNAME: apikey
      MAIL_PASSWORD: your-sendgrid-api-key
      MAIL_ENCRYPTION: tls
      MAIL_FROM_ADDRESS: support@your-domain.com
      MAIL_FROM_NAME: "Your Support"
    ports:
      - "8080:80"
    volumes:
      - freescout_storage:/var/www/html/storage
      - freescout_public:/var/www/html/public
    command: >
      sh -c "php artisan migrate --force &&
             php artisan freescout:after-app-update &&
             php artisan storage:link &&
             php-fpm"

  queue:
    image: freescoutapp/freescout:latest
    depends_on:
      - mysql
      - freescout
    environment:
      APP_URL: http://localhost:8080
      APP_ENV: production
      APP_KEY: base64:change_me_to_a_random_string
      DB_HOST: mysql
      DB_PORT: 3306
      DB_DATABASE: freescout
      DB_USERNAME: freescout
      DB_PASSWORD: freescout_password
    volumes:
      - freescout_storage:/var/www/html/storage
    command: php artisan queue:work database --sleep=3 --tries=3 --timeout=60

volumes:
  mysql_data:
  freescout_storage:
  freescout_public:
EOF

Replace these values:

  • root_password_here — strong password for MySQL root
  • freescout_password — password for freescout user
  • your-sendgrid-api-key — your SendGrid API key
  • support@your-domain.com — your support email
  • APP_KEY — generate a random string: php -r "echo base64_encode(random_bytes(32));"

Step 3: Generate APP_KEY

Generate a cryptographically secure key:

docker run --rm freescoutapp/freescout php -r "echo base64_encode(random_bytes(32));"

Copy the output and paste it into docker-compose.yml for both freescout and queue services.


Step 4: Start the Containers

cd ~/freescout
docker-compose up -d

This starts three containers:

  • mysql — database
  • freescout — main application (port 8080)
  • queue — background worker for emails

Check they're running:

docker-compose ps

You should see three containers with status Up.


Step 5: Wait for Initialization

FreeScout takes 30–60 seconds to initialize on first run:

docker-compose logs -f freescout

Wait until you see:

[info] Starting PHP-FPM...

Then press Ctrl+C.


Step 6: Access FreeScout

Open your browser to:

http://localhost:8080

(If running on a remote server, use the server's IP instead.)

Complete the web installer:

  1. Check system requirements (all should be green)
  2. Create admin account
  3. Configure your first mailbox
  4. Set email preferences

Step 7: Set Up Reverse Proxy with NGINX (for HTTPS)

If you want HTTPS with a domain, add NGINX:

Create nginx.conf:

cat > nginx.conf << 'EOF'
upstream freescout {
  server freescout:80;
}

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    location / {
        proxy_pass http://freescout;
        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;
    }
}
EOF

Update docker-compose.yml to add NGINX service:

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - freescout

Restart:

docker-compose down
docker-compose up -d

Step 8: Add SSL with Let's Encrypt (Optional)

If using NGINX reverse proxy:

sudo apt install -y certbot
sudo certbot certonly --standalone -d your-domain.com -d www.your-domain.com

Copy certificates to your docker folder:

mkdir -p ~/freescout/ssl
sudo cp /etc/letsencrypt/live/your-domain.com/fullchain.pem ~/freescout/ssl/
sudo cp /etc/letsencrypt/live/your-domain.com/privkey.pem ~/freescout/ssl/
sudo chown $USER:$USER ~/freescout/ssl/*

Update nginx.conf with SSL configuration (advanced topic — see NGINX SSL docs).


Docker Commands You'll Need

Check Logs

# All services
docker-compose logs -f

# Specific service
docker-compose logs -f freescout
docker-compose logs -f queue

Restart Services

# Restart all
docker-compose restart

# Restart one service
docker-compose restart freescout

Stop Everything

docker-compose down

Update FreeScout (Pull Latest Image)

docker-compose pull freescout
docker-compose up -d freescout

Access MySQL Console

docker-compose exec mysql mysql -u freescout -p freescout

View Resource Usage

docker stats

Docker Volumes Explained

Three volumes are created:

  • mysql_data — stores database (persistent)
  • freescout_storage — stores uploads, logs, cache (persistent)
  • freescout_public — stores public files (persistent)

Even if containers crash or are deleted, volumes persist. Data is never lost.

To back up volumes:

docker run --rm -v freescout_mysql_data:/data -v $(pwd):/backup alpine tar czf /backup/mysql_backup.tar.gz /data

Scaling with Docker

Run Multiple Queue Workers

Edit docker-compose.yml:

  queue1:
    image: freescoutapp/freescout:latest
    # ... same config ...
    
  queue2:
    image: freescoutapp/freescout:latest
    # ... same config ...
    
  queue3:
    image: freescoutapp/freescout:latest
    # ... same config ...

Three workers = 3x email processing speed.

Run on Docker Swarm or Kubernetes

For enterprise deployment, you can orchestrate FreeScout across multiple machines using Docker Swarm or Kubernetes. Advanced topic — beyond this guide.


Common Docker Issues

| Issue | Cause | Fix | |---|---|---| | "Cannot connect to Docker daemon" | Docker not started | sudo systemctl start docker | | Port 8080 already in use | Another app using port | Change port in docker-compose.yml: 8081:80 | | MySQL won't start | Data corruption | docker-compose down && docker volume rm freescout_mysql_data (⚠️ loses data) | | Emails not sending | SMTP credentials wrong | Check env vars in docker-compose.yml | | Queue not working | Queue container crashed | docker-compose logs queue to see errors |


Docker vs Traditional VPS

| | Docker | VPS | |---|---|---| | Setup time | 5 min | 4 hours | | Portability | Run anywhere | Locked to one server | | Resource overhead | ~10% more | None | | Scaling | Easy (more containers) | Hard (migrate VPS) | | Backups | Volume snapshots | Full disk backups | | Learning curve | Medium | Low | | Best for | Developers, testing, teams with Docker experience | Traditional sysadmins, long-term production |

Want FreeScout Docker deployment configured and optimized?

We handle the full FreeScout installation on your server — SSL, email, security hardening, and a 1-hour onboarding call. Done in 24 hours.

One-time fee · 30-day support · Money-back guarantee


Next Steps

  1. Persistent Storage: Move data to a network volume (NFS, Ceph) for production
  2. Monitoring: Add Prometheus/Grafana for container metrics
  3. Auto-scaling: Use Kubernetes for automatic scaling based on load
  4. CI/CD: Automate FreeScout updates with GitLab CI or GitHub Actions

For now, you have a working FreeScout instance in 30 minutes with zero Linux configuration. That's the power of Docker.

Resources

Need FreeScout Installed Professionally?

Skip the complexity. We install and configure FreeScout on your server in 24 hours — SSL, email, security, and a full onboarding call included.

Get It Done for $100

One-time fee · 30-day support · Money-back guarantee

Related Articles