> For the complete documentation index, see [llms.txt](https://gift.icbest.ca/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gift.icbest.ca/getting-started/installation.md).

# Installation

### Tags and Versions

{% hint style="success" %}
Images are available in amd64 and arm64 under the same tag name (v2.6.0 and upward).
{% endhint %}

Docker images use the following tagging conventions:

* **Version-specific tags (English):** `:v2.4.1`
* **Version-specific tags (other languages):** `:v2.4.1-fr`

  > Refer to the table below to find the earliest available version in your language.
* **Latest version (English):** `:latest`
* **Latest version (other languages):** `:latest-fr`

  > Use these tags to always pull the most up-to-date image in the desired language, if available.

| Language | Code    | Earliest Available Version |
| -------- | ------- | -------------------------- |
| English  | DEFAULT | ALL VERSIONS               |
| French   | fr      | v2.4.1                     |
| Dutch    | nl      | v2.4.3                     |
| Swedish  | sv      | v2.4.3                     |

{% hint style="info" %}
For more detailed information regarding the Dockerfile, please review the inline comments in the GitHub repository.
{% endhint %}

### Docker Compose

The image is on Docker Hub: [icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager). It uses the same latest code as the "Main" folder on the GitHub repo.

Copy the file [docker-compose.yml](https://github.com/icbestCA/giftmanager/blob/main/docker-compose.yml) from the repo to your machine, then edit it:

**1. Secret key (required).** Generate a private random value and save it in a `.env` file next to `docker-compose.yml` (never commit this file):

```python
python -c 'import secrets; print("SECRET_KEY=" + secrets.token_hex(32))' > .env
```

**2. Data volume.** Change only the left part to a folder on your machine:

```yaml
volumes:
  - C:/Users/user1/documents/data:/app/data
```

When updating, keep the files where they are and create a new container mounted to the same folder.

**3. Port.** Edit the port you want to expose:

```yaml
ports:
  - "[port]:5000"
```

**4. Emails (optional).** Uncomment either the SMTP or the Mailjet block in the file. See Email notifications.

**5. Run it.** From the folder containing `docker-compose.yml`:

```yaml
docker compose up -d && docker compose logs -f
```

You should see the image being pulled and the Flask app starting. After changing any environment variable or secret, recreate the container with `docker compose up -d --force-recreate`.

For additional customization, see [Gunicorn Parameters](/getting-started/environnement-variables.md#docker-gunicorn-variables).

Now head to [setup](/getting-started/setup.md) and follow the steps to configure the app.

***

#### Email notifications

Email is optional. The only email sent is a notification to the buyer when a gift idea they already bought is deleted. Mailjet is the default provider; set `EMAIL_PROVIDER=smtp` to use an SMTP server instead. There is no automatic fallback between the two.

For SMTP, set these environment variables (see the full list on the Environment variables page):

```yaml
environment:
  EMAIL_PROVIDER: smtp
  SYSTEM_EMAIL: notifications@example.com
  SMTP_HOST: smtp.example.com
  SMTP_PORT: "587"
  SMTP_SECURITY: starttls
  SMTP_USERNAME: your-smtp-login
  SMTP_PASSWORD_FILE: /run/secrets/smtp_password   # or SMTP_PASSWORD, not both
```

Use `587` with `starttls`, or `465` with `ssl`. Use `none` only for a trusted local relay without login.

To use a password file, create `./secrets/smtp_password` containing only the password, then add the secret to the service:

```yaml
services:
  giftmanager:
    secrets:
      - smtp_password

secrets:
  smtp_password:
    file: ./secrets/smtp_password
```

To test, sign in as administrator, open **Email Settings**, enter a recipient under **Test Email Delivery** and select **Send Test Email**. A success message means the server accepted the mail, so also check the inbox and the From address. If it fails, run `docker compose logs --tail=50 giftmanager` (logs show the error type only, never passwords or addresses).

***

### Docker Run

The image is on Docker Hub: [icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager).

```sh
docker run -p [published-port]:5000 -d \
  -e SECRET_KEY=your-private-random-value \
  -v /path/to/data:/app/data \
  --name giftmanager icbest/giftmanager
```

* Change the port to the one you want to use, for example `80:5000` to reach the app on port 80.
* Add a path so the app stores its data on the host:
  * Linux: `/root/data:/app/data`
  * Windows: `C:/Users/user1/documents/data:/app/data`
* Secrets (like `SECRET_KEY`) must be passed with `-e`. Email options are also set with `-e` (see Environment variables).
* When updating, keep the files where they are and create a new container mounted to the same folder.

For additional customization, see [Gunicorn Parameters](/getting-started/environnement-variables.md#docker-gunicorn-variables).

Now head to [setup ](/getting-started/setup.md)and follow the steps to configure the app.

### Python Gunicorn (Linux Only)

Make sure you have the latest Python and pip installed.

1. Download the app folder from the [main repository](https://github.com/icbestCA/giftmanager) and unzip it somewhere that makes sense to you.
2. Inside the main directory, install the requirements:

```sh
   pip install -r requirements.txt
```

3. Set your secrets as environment variables (they are no longer read from the UI or `settings.json`):

```sh
   export SECRET_KEY="your-private-random-value"
```

4. Still in the `app.py` directory, deploy with [Gunicorn](https://gunicorn.org/). You can access it on port 80:

```sh
   gunicorn app:app -w 1 --threads 4 -b 0.0.0.0:80
```

* `-w 1`: number of workers. Keep it at 1, because the JSON database glitches with multiple workers.
* `--threads 4`: threads inside that one worker, for faster loading.
* `-b 0.0.0.0:80`: the published port. Port 80 is the default for http.
* `app:app`: the file and Flask object to run.

5. Go to [setup](/getting-started/setup.md) and follow the steps.
