# Install with Kamal

Kamal builds the image from your clone on your computer and deploys it to your server, so you can change the code. To run the ready-made image as one container without Kamal, [install with Docker](https://mailpiece.dev/docs/docker).

Paste this into your agent:

> Install Mailpiece on my server with Kamal. Read mailpiece.dev/llms.txt first.

## What you need

A server you reach over SSH, with ports `80` and `443` open and a domain pointed at it, such as `app.example.com`. `kamal setup` installs Docker on it if it's missing, which works on Linux. The image is built for `amd64`; for an ARM server, set `builder.arch` in your destination file.

**Mail.** SMTP for the app's own mail, such as sign-in codes, and a provider or SMTP server for the newsletter's, set in the app on Settings › Outgoing mail. See [Mail](https://mailpiece.dev/docs/mail).

**For Kamal, on your machine.** Git, Docker to build the image and the Ruby in `.ruby-version`. No registry account is needed.

## Get the code

```sh
git clone https://github.com/mailpiece/mailpiece.git
cd mailpiece
bundle install
```

## Describe your server

`config/deploy.yml` is shared; yours goes in a destination file of your own name, so a pull never touches it. The proxy host and `BASE_URL` are the same address.

```sh
# config/deploy.production.yml
servers:
  web:
    hosts:
      - 203.0.113.10

volumes:
  - mailpiece_live:/rails/storage

proxy:
  ssl: true
  hosts:
    - app.example.com

ssh:
  user: root

env:
  clear:
    RAILS_ENV: production
    BASE_URL: https://app.example.com
    MAILER_FROM_ADDRESS: My Newsletter <hello@example.com>
```

## Set the secrets

Every secret `config/deploy.yml` lists goes in `.kamal/secrets.production`, read from your shell or a password manager. See [Configuration](https://mailpiece.dev/docs/configuration).

Make `SECRET_KEY_BASE` once and keep it safe apart from the server: the relay token and SMTP password Mailpiece stores are encrypted with keys derived from it. A new one also signs everyone out, and the rating links in issues already mailed stop answering.

```sh
# Make SECRET_KEY_BASE once
openssl rand -hex 64

# .kamal/secrets.production
SECRET_KEY_BASE=$SECRET_KEY_BASE
SMTP_ADDRESS=$SMTP_ADDRESS
SMTP_USERNAME=$SMTP_USERNAME
SMTP_PASSWORD=$SMTP_PASSWORD
S3_ACCESS_KEY_ID=$S3_ACCESS_KEY_ID
S3_ENDPOINT=$S3_ENDPOINT
S3_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY
```

## Deploy

The first time, `setup` installs Docker on the server, builds the image, starts the app and gets the certificate. The databases are created on first start. Use `setup` this once; after, `deploy`.

Set up [backups](https://mailpiece.dev/docs/backups) of the `mailpiece_live` volume.

```sh
bin/kamal setup -d production
```

## Open it

Go to `/signup`, as in `https://app.example.com/signup`. Until the first account exists the sign-in code is shown on screen, so this works before mail is set up; after, it goes by email.

The first person is staff and sees the job queue at `/admin/jobs`. Signup closes after the first account unless `MULTI_TENANT` is `true`; a signed-in person can still start another newsletter from the account menu.

## Update it

Your destination file and its secrets are git-ignored, so a pull never touches them.

```sh
git pull
bin/kamal deploy -d production
```

## More than one environment

Each is another destination: `config/deploy.<name>.yml`, with its secrets in `.kamal/secrets.<name>`.

```sh
bin/kamal deploy -d <name>
```

## Day to day

```sh
bin/kamal console -d production
bin/kamal shell -d production
bin/kamal logs -d production
```

## Then

Take your [first steps](https://mailpiece.dev/docs/first-steps).

Still need help? Ask on [GitHub](https://github.com/mailpiece/mailpiece).
