import Alert from "@/components/DocsAlert";
import SupportOptions from "@/components/SupportOptions";
import CodeBlock from "@/components/CodeBlock";

# Install Firezone with Docker

As of 0.6.0, Docker is now the **preferred method** for deploying Firezone.
Docker offers a number of benefits over the old
[Omnibus method](/docs/deploy/omnibus):

- **Simpler, more robust upgrades**: In most cases, simply pull the latest
  `firezone/firezone` image and restart the container.
- **Simpler configuration**: Most day-to-day configuration of Firezone can now
  be done in the web UI instead of the `/etc/firezone/firezone.rb` configuration
  file. All other configuration variables can be specified as ENV vars to the
  Firezone container.
- **Smaller footprint**: The Firezone image weighs in at a couple dozen
  megabytes versus hundreds of megabytes for the Omnibus package.
- **Portability**: Firezone now runs on any platform that supports Docker.
- **Security**: Containerization providers better security isolation than simply
  running as an unprivileged local user.

## Step 1: Prerequisites

- Ensure you're on a
  [supported platform](/docs/deploy/docker/supported-platforms) with
  [ docker-compose](https://docs.docker.com/compose/install) **version 2 or
  higher** installed.
- Ensure port forwarding is enabled on your firewall. The default Firezone
  configuration requires the following ports to be open:
  - `80/tcp` (optional): For automatically issuing SSL certificates.
  - `443/tcp`: To access the web UI.
  - `51820/udp`: VPN traffic listen port.

<Alert
  color="warning"
  html={`
Before deploying Firezone in <strong>production</strong>, you'll need a valid DNS record
pointing to this instance. See <a href="/docs/deploy/#prepare-to-deploy">Prepare to
Deploy</a> if you haven't done this already.
`}
/>

## Step 2: Install server

After prerequisites are satisfied, you're ready to install the Firezone Server.

### Option 1: Automatic install

The easiest way to deploy Firezone with Docker is the automatic install script:

<CodeBlock
  language="bash"
  codeString="bash <(curl -fsSL https://github.com/firezone/firezone/raw/legacy/scripts/install.sh)"
/>

This will ask you a few questions regarding initial configuration, then proceed
to download a sample docker-compose.yml file, configure it with your responses,
and then print instructions for accessing the Web UI.

Firezone files will be installed in `$HOME/.firezone` by default.

### Option 2: Manual install

If the automatic install fails, or you'd just like more control over the
installation process, follow the steps below to install manually.

1. Download the docker compose template to a local working directory: **For
   Linux**:

```
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/legacy/docker-compose.prod.yml -o docker-compose.yml
```

**For macOS, Windows (non-production only)**:

```
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/legacy/docker-compose.desktop.yml -o docker-compose.yml
```

1. Generate required secrets:

```
docker run --rm firezone/firezone bin/gen-env > .env
```

2. At a minimum, change the `DEFAULT_ADMIN_EMAIL` and `EXTERNAL_URL` variables.
   Optionally modify other secrets as needed.
3. Migrate the database:

```
docker compose run --rm firezone bin/migrate
```

4. Create the first admin:

```
docker compose run --rm firezone bin/create-or-reset-admin
```

5. Bring the services up: `docker compose up -d`

You should now be able to access the Firezone web portal at the `EXTERNAL_URL`
variable you defined above.

## Step 3 (optional): Enable on boot

If you'd like Firezone to start automatically on boot, first ensure Docker is
enabled at startup:

```bash
sudo systemctl enable docker
```

Then, make sure your Firezone services have the `restart: always` or
`restart: unless-stopped` option specified in the `docker-compose.yml` file.
This is the default used in the docker-compose.prod.yml production template
file.

## Step 4 (optional): Enable IPv6

By default, Firezone ships with IPv6 connectivity enabled inside the tunnel but
not routable to the public internet. To enable IPv6 support in Docker-deployed
Firezone, follow the steps below.

1. Enable IPv6 support within Docker by adding the following to
   `/etc/docker/daemon.json`:

```json
{
  "ipv6": true,
  "ip6tables": true,
  "experimental": true,
  "fixed-cidr-v6": "fcff:db8:1::/64"
}
```

This enables IPv6 NAT and configures IPv6 forwarding for Docker containers.

1. Enable router advertisements on boot for your default egress interface:

```bash
egress=`ip route show default 0.0.0.0/0 | grep -oP '(?<=dev ).*' | cut -f1 -d' ' | tr -d '\n'`
sudo bash -c "echo net.ipv6.conf.${egress}.accept_ra=2 >> /etc/sysctl.conf"
```

2. Reboot

You should now be able to ping google from within a docker container:

```bash
docker run --rm -t busybox ping6 -c 4 google.com
```

You shouldn't need to manually add any `iptables` rules to enable IPv6
SNAT/masquerading for tunneled traffic; Firezone handles this for you by default
on start.

## Step 5: Install client apps

<Alert
  color="info"
  html={`
Firezone currently uses WireGuard's <a href="https://www.wireguard.com/install">
open-source client apps</a>.
`}
/>

Once successfully deployed, users and devices can be added to connect to the VPN
server:

- [Add Users](/docs/user-guides/add-users): Add users to grant them access to
  your network.
- [Client Instructions](/docs/user-guides/client-instructions): Instructions to
  establish a VPN session.

<SupportOptions />

## Post Setup

Congrats! You have completed the setup, but there's a lot more you can do with
Firezone:

- [Integrate your identity provider](/docs/authenticate) for authenticating
  clients
- Using Firezone as a NAT gateway to
  [establish a static IP for your team](/docs/user-guides/use-cases/nat-gateway)
- Create tunnels between multiple peers with
  [reverse tunnels](/docs/user-guides/use-cases/reverse-tunnel)
- Only route certain traffic through Firezone with
  [split tunneling](/docs/user-guides/use-cases/split-tunnel)
