# Redirect from www to non-www with Kamal and Traefik

I recently wrote an article about how [I do deployments with Kamal](https://lesscodeworks.com/how-to-deploy-with-kamal-on-a-single-server), which included setting up SSL for your domain and redirecting from non-ssl to ssl. In this article, I want to go further and show you how I redirect from www to non-www.

In the `config` folder, I have 3 yaml files: `deploy.yml`, `deploy.development.yml`, and `deploy.production.yml`.

`deploy.yml` contains the shared configuration across environments. Then, in each `deploy.*.yml`, I add the specifics for each environment, such as the server IP address, different domain names, etc.

```yaml
# config/deploy.yml
​
# Name of your application.
service: my_app
​
image: username/image_name
​
registry:
  # Specify the registry server
  username: registry_username
  password:
    - KAMAL_REGISTRY_PASSWORD
​
env:
  clear:
    HOSTNAME: your_hostname
  secret:
    - KAMAL_REGISTRY_PASSWORD
    - add_any_other_secrets_here

traefik:
  options:
    publish:
      - "443:443"
    volume:
      - "/letsencrypt/acme.json:/letsencrypt/acme.json"
  args:
    entryPoints.web.address: ":80"
    entryPoints.websecure.address: ":443"
    entryPoints.web.http.redirections.entryPoint.to: websecure
    entryPoints.web.http.redirections.entryPoint.scheme: https
    entryPoints.web.http.redirections.entrypoint.permanent: true
    certificatesResolvers.letsencrypt.acme.email: "your_email_address"
    certificatesResolvers.letsencrypt.acme.storage: "/letsencrypt/acme.json"
    certificatesResolvers.letsencrypt.acme.httpchallenge: true
    certificatesResolvers.letsencrypt.acme.httpchallenge.entrypoint: web


# add this if you are using a different route and port than kamal's defaults
healthcheck:
  path: /
  port: 1234
```

Before you begin the deployment process for the first time, remember to create the necessary folders and Docker network:

* Setup the directory for Let's encrypt
    
    ```yaml
      mkdir -p /letsencrypt && touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json
    ```
    
* create a Docker network called `private`
    
    ```yaml
      docker network create -d bridge private
    ```
    
    The reason we're using a Docker private network is that when you open a port in Kamal, it becomes accessible to everyone. This happens because Docker automatically adds it to the iptables firewall.
    

Now let's see how `config.development.yml` looks like:

```yaml
servers:
  web:
    hosts:
      - put_your_deployment_server_ip_address_here
    labels:
      traefik.http.routers.devproject_secure.entrypoints: websecure
      traefik.http.routers.devproject.rule: Host(`your_domain.tld`) || Host(`www.your_domain.tld`)
      traefik.http.routers.devproject_secure.rule: Host(`your_domain.tld`) || Host(`www.your_domain.tld`)
      traefik.http.routers.devproject_secure.tls: true
      traefik.http.routers.devproject_secure.tls.certresolver: letsencrypt
      traefik.http.routers.devproject_secure.middlewares: redirect-to-non-www
      traefik.http.middlewares.redirect-to-non-www.redirectregex.regex: ^https?://www.your_domain.tld/(.*)
      traefik.http.middlewares.redirect-to-non-www.redirectregex.replacement: https://your_domain.tld/$1
      traefik.http.middlewares.redirect-to-non-www.redirectregex.permanent: true

builder:
  multiarch: false
```

### Accepting traffic from domain and subdomain

To accept traffic from both the www subdomain and our main domain in our router, we can simply use `||` (OR) to include both hosts. By doing this, we'll accept incoming traffic from both and also obtain an SSL certificate for them.

### Middlewares

```yaml
traefik.http.routers.devproject_secure.middlewares: redirect-to-non-www
```

We hook up a new middleware caled: `redirect-to-non-www` to our `devproject_secure` router.

### Regex middleware to redirect www to non-www

```yaml
traefik.http.middlewares.redirect-to-non-www.redirectregex.regex: ^https?://www.your_domain.tld/(.*)
      traefik.http.middlewares.redirect-to-non-www.redirectregex.replacement: https://your_domain.tld/$1
      traefik.http.middlewares.redirect-to-non-www.redirectregex.permanent: true
```

This part is straightforward: we specify the regex expression, define the replacement, and enable 301 redirects by setting it to `true`.

Now, you can deploy your app (or update your configuration), but don't forget to run `kamal traefik reboot` every time you change Traefik settings.

I began using Traefik when I started deploying with kamal, and I'm currently learning about what it can do and how.
