This project uses yarn and yarn workspaces for package.json splitting and convenience.
$> npm -v
11.11.0
$> npm install -g corepack
$> yarn init -2
$> yarn --version
4.13.0
$> node -v
v25.8.0For Tauri, you need to install the Rust toolchain and system dependencies:
# Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Linux system dependencies
sudo apt install libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelfFor testing and developing on the project with true hot module replacement, run:
yarn startFor testing in the Tauri desktop app (dev mode):
yarn tauri:devFor building the Tauri desktop app:
yarn tauri:buildFor building the production website and deploying it, run:
yarn build
yarn deployYou can now stop the task on AWS ECS, it will restart automatically if you did not define an autoscaling policy.
Remember to invalidate the cache on your AWS Redis instance.
Connect with SSH to your EC2 instance, then connect to your Redis instance as explained in the ElastiCache documentation.
https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/GettingStarted.ConnectToCacheNode.html#GettingStarted.ConnectToCacheNode.Redis.NoEncrypt
Then run flushall. You should automate this part.
More information in the cache part below.
For running the test suite:
yarn testFor displaying coverage:
yarn coverFor displaying lint errors:
yarn eslintThe desktop app is built with Tauri v2 and lives in packages/tauri/ (manifest) and src-tauri/ (Rust backend).
src-tauri/ # Rust backend (Cargo.toml, tauri.conf.json, src/)
packages/tauri/ # npm package wrapping the Tauri CLI
src/client/ # main-tauri.js — dedicated entry point (no SSR, no loadable)
config/
rspack.config.tauri.js # Rspack build config for the Tauri frontend
generateTauriIndex.js # Generates public/index.html before the Tauri build
- In dev mode, Tauri loads your Koa SSR server at
https://localhost:3000viadevUrl. - In production build, a static frontend is compiled by Rspack (
yarn build:tauri) intopublic/dist/tauri/, then bundled into the desktop app by Tauri. @loadable/componentis aliased to a thinReact.lazywrapper (src/lib/loadable-static.js) so the existing app code works without SSR infrastructure.
| Command | Description |
|---|---|
yarn tauri:dev |
Start the desktop app in dev mode (starts the Koa server automatically) |
yarn tauri:build |
Build the static frontend then package the desktop app |
Icons are generated from the source PNG using the Tauri CLI:
npx tauri icon src/assets/img/launcher-icon-high-res.pngThis generates all required sizes and formats (.ico, .icns, PNG variants) into src-tauri/icons/.
This project uses a Redis cache manager for the server routes, avoiding re-rendering the same HTML per route.
For deploying with Amazon, please create a Redis cluster by following this documentation: https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/GettingStarted.CreateCluster.html
Don't forget to create an isolated security group for opening port 6379 as described in the documentation. For keeping costs low on Amazon, you can simply run a Redis Docker instance on your EC2 instance and get the container instance IP for your Redis.
$> docker run --name redis -p 6379:6379 -d redis
$> docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redisYou will need to go inside this Docker container for flushing the cache in the future.
$> docker exec -it redis bash
# redis-cli flushallFor testing your generated Docker image with your locally hosted Redis, update your deploy.js file and do not forget to comment out the part that pushes to your registry, then:
$> redis-cli flushall && docker run -it -v /etc/letsencrypt/:/etc/letsencrypt/ --net="host" -p 8000:8000 docker_image_name:latestYou'll notice the Let's Encrypt folder is also bound — more information in the next section.
Then head to https://localhost:8001/
Remember to redis-cli flushall when testing multiple times.
On your EC2 instance:
sudo yum install certbot/etc/nginx/conf.d/guillaumecisco.conf
# HTTP
server {
listen 80;
server_name guillaumecisco.com www.guillaumecisco.com;
# ACME challenge (required for Let's Encrypt)
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
default_type "text/plain";
try_files $uri =404;
}
# Redirect everything else to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS
server {
listen 443 ssl;
server_name guillaumecisco.com www.guillaumecisco.com;
ssl_certificate /etc/letsencrypt/live/guillaumecisco.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/guillaumecisco.com/privkey.pem;
# ACME challenge (also required here)
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
default_type "text/plain";
try_files $uri =404;
}
# Proxy to Docker container
location / {
proxy_pass https://127.0.0.1:8001;
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;
proxy_ssl_server_name on;
proxy_ssl_verify off;
}
}Reload nginx:
sudo systemctl reload nginxsudo certbot certonly --webroot -w /var/www/html -d guillaumecisco.com -d www.guillaumecisco.comCertificates are generated here:
/etc/letsencrypt/live/guillaumecisco.com/
Add a cron job:
sudo crontab -e0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"- Runs every day at 03:00
- Renews only if needed (<30 days before expiration)
- Reloads nginx only if the certificate was renewed
sudo certbot renew --dry-run- The directory
/var/www/html/.well-known/acme-challengemust be accessible - Port 80 must remain open (AWS Security Group)
- Do not remove this nginx block:
location ^~ /.well-known/acme-challenge/certbot-autois deprecated → do not usestandalonemode is not compatible with nginx in production- Manual renewal is no longer required
Mount certificates into your container:
-v /etc/letsencrypt/:/etc/letsencrypt/- Automatically renewed valid certificate
- Zero downtime
- No manual intervention required
$> aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 984406419997.dkr.ecr.eu-central-1.amazonaws.comCreate a deploy.js file with the right variables.
$> sudo systemctl reload nginx




