Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The dependable production pattern is a Phoenix release running under systemd, MySQL on the same VPS or a private managed service, and nginx handling the public HTTP(S) connection. Build the release with the same Elixir, Erlang/OTP, operating-system family, and CPU architecture as the target machine; inject DATABASE_URL, SECRET_KEY_BASE, PHX_HOST, and PORT at runtime; run the release migration before starting the web process; then put nginx and automated TLS in front of Phoenix.
What you are building
A production deployment has four separate responsibilities:
Free tools Windows power users keep installed
One-click scans. No signup required.
- Phoenix release: a self-contained directory containing the Erlang VM, Elixir runtime, application code, and dependencies. It is the artifact you copy to the server.
- MySQL: the data service, installed locally or reached over a private network. Phoenix connects through Ecto and the MyXQL adapter.
- systemd: starts the release at boot, restarts it after a failure, and provides a consistent place to inspect service logs.
- nginx: listens on public ports 80 and 443, forwards requests to Phoenix on a private loopback port, and preserves the proxy headers Phoenix needs.
Phoenix should not be exposed directly on the public interface. Bind the application to a private address and allow only SSH, HTTP, and HTTPS through the firewall. A single VPS is straightforward to operate, but you remain responsible for operating-system updates, database backups, restore tests, capacity planning, and rollback.
Decide where MySQL runs
| Topology | Operational ownership | Network path | Backup and restore | Upgrade and rollback | When it fits |
|---|---|---|---|---|---|
| Phoenix and MySQL on one VPS | You patch and monitor both services. | Local connection with minimal network latency. | You schedule backups and store copies away from the VPS; restoration is your responsibility. | One machine makes coordinated changes simple, but a host failure affects both tiers. | Small applications and teams that want the fewest moving parts. |
| Phoenix VPS plus managed MySQL | The provider operates the database platform; you still manage schema changes and credentials. | Private-network latency and firewall rules must be verified. | Provider features may help, but you still need an independent restore test. | Database maintenance is separated from application releases, while network and credential changes add coordination. | Applications that need database separation or managed backups. |
| Containerized Phoenix release | You operate images, runtime orchestration, logs, and persistent-data boundaries. | Depends on the container network and placement. | Database storage and backup policy must be designed separately from ephemeral containers. | Immutable image rollouts can simplify rollback, but the platform adds complexity. | Teams already operating containers and needing a repeatable deployment platform. |
Official Phoenix and Ubuntu documentation does not prescribe a universal VPS size, traffic limit, uptime figure, or zero-downtime method. Choose CPU, memory, storage, and topology from your workload, connection pool, asset-processing needs, and database growth, then measure the running system.
#1 Best Overall
- Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
- With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
- Wide Application: attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
- Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
- Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.
Prerequisites and variables
You need:
- A Linux VPS with console or SSH access and a DNS name such as
example.com. - A non-root account for deploying and running Phoenix.
- Administrative access for package installation, firewall rules, nginx, and systemd.
- Elixir and Erlang/OTP versions pinned to the versions used by the application and build artifact.
- A build host whose operating-system family and CPU architecture are compatible with the VPS.
- A Phoenix project configured for MySQL, with its release name and OTP application name known.
The examples use an application named my_app, an Ecto repository named MyApp.Repo, Phoenix on port 4000, and the domain example.com. Replace every example value before production use.
1. Prepare and harden the VPS
Create a deployment account
sudo adduser --disabled-password --gecos "" deploy
sudo usermod -aG sudo deploy
Install security updates with the package manager supplied by your distribution, then log in as deploy for application work. Keep root access for administration only. Configure SSH keys, disable password authentication after confirming key login, and retain a tested administrative access path before changing SSH settings.
Set the firewall policy
On an Ubuntu-style system, allow SSH, HTTP, and HTTPS and deny unsolicited inbound traffic. If SSH uses a nonstandard port, allow that port instead of blindly copying the example.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Do not open Phoenix’s private port or MySQL’s port to the internet. If MySQL is managed elsewhere, permit its private address and required TLS connection rather than enabling broad public access.
Point DNS at the server
Create an address record for the hostname you will place in PHX_HOST. Wait until it resolves to the VPS before requesting a certificate. Keep the DNS name, release name, service name, and filesystem path consistent; mismatches are a common cause of an apparently healthy service that cannot be reached through nginx.
2. Install and secure MySQL
Install the distribution package
sudo apt update
sudo apt install mysql-server
Ubuntu package installations use systemd for MySQL startup and shutdown. Confirm that it is running before configuring the application:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #2
- Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
- Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
- Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
- Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
- Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth
sudo systemctl enable --now mysql
sudo systemctl status mysql
Run the security hardening procedure supplied by your distribution, remove anonymous or test accounts you do not need, and keep MySQL bound to localhost or a private interface unless a remote application connection is intentional.
Create a dedicated database and account
Use a separate database user with only the privileges required by the application. Replace the example password with a long, unique value and protect it as a secret.
sudo mysql
CREATE DATABASE my_app_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'my_app'@'localhost' IDENTIFIED BY 'replace-with-a-unique-password';
GRANT ALL PRIVILEGES ON my_app_prod.* TO 'my_app'@'localhost';
FLUSH PRIVILEGES;
EXIT;
If Phoenix and MySQL are on different hosts, create the account for the application host or private subnet, enforce MySQL TLS as required by your policy, and restrict the database firewall to that source. Never use the MySQL administrative account in DATABASE_URL.
Verify connectivity before deployment
mysql -u my_app -p -h 127.0.0.1 my_app_prod
Use the same hostname, port, database name, and credentials that will appear in the Phoenix connection URL. A successful interactive login isolates database, network, and credential problems before Phoenix is involved.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute3. Configure Phoenix for MySQL
Generate or adapt the project
Phoenix’s generator supports MySQL directly:
mix phx.new my_app --database mysql
This selects the MyXQL adapter through Ecto. For an existing project, inspect its repository configuration and dependencies to confirm that the MyXQL adapter is present and that migrations target the intended repository.
Keep environment-specific values out of source control. The checked-in configuration can describe how values are read; production values belong in the service environment or a protected environment file.
Rank #3
- 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
- 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
- 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
- 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
- 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.
4. Put runtime configuration in a protected environment
Release configuration is evaluated on the production machine, so the artifact can be identical across environments while credentials differ. Create a root-owned file readable only by the service account:
sudo install -d -m 750 /etc/my_app
sudo touch /etc/my_app/my_app.env
sudo chown root:deploy /etc/my_app/my_app.env
sudo chmod 640 /etc/my_app/my_app.env
Place values like these in that file:
DATABASE_URL=mysql://my_app:URL_ENCODED_PASSWORD@127.0.0.1/my_app_prod
SECRET_KEY_BASE=your-generated-production-secret
PHX_HOST=example.com
PORT=4000
PHX_SERVER=true
DATABASE_URLidentifies the MySQL user, password, host, port if nonstandard, and database. URL-encode characters that have a special meaning in a URL.SECRET_KEY_BASEmust be a strong production secret and must not be committed to the repository. Generate it using the Phoenix-supported secret-generation command or another cryptographically secure process.PHX_HOSTis the public hostname used when Phoenix builds URLs and validates host-related settings.PORTis the private listener nginx will proxy to. The firewall should not expose it publicly.PHX_SERVER=trueensures the release starts the Phoenix endpoint when using a generic release start command; follow the generated release’s runtime configuration if it uses a dedicated server helper instead.
Review the generated config/runtime.exs rather than assuming these variable names are wired automatically. Confirm the release name, repository module, pool size, SSL requirements, and any additional application-specific settings.
5. Build a production release
Use a compatible build host
Build on a machine compatible with the VPS operating-system family and architecture. Pin the Elixir and Erlang/OTP versions used by the project; a release built for an incompatible architecture or runtime can fail before Phoenix starts. Keep dependency and asset tooling available on the build host, not on the minimal production machine.
Compile and package
From the project directory, run the production dependency, compilation, asset, and release steps:
MIX_ENV=prod mix deps.get --only prod
MIX_ENV=prod mix compile
MIX_ENV=prod mix assets.deploy
mix phx.gen.release
MIX_ENV=prod mix release
Run mix phx.gen.release once when setting up the release scripts, then commit the generated release files. The resulting directory under _build/prod/rel/my_app contains the VM, Elixir, application code, and dependencies. It does not contain Mix, so production operations must use the generated release scripts rather than commands such as mix ecto.migrate.
Keep the release immutable: build it once, record the source revision and runtime versions, and copy that exact directory to the VPS. Do not compile ad hoc on the production server unless your recovery procedure explicitly requires it.
Rank #4
- 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
- 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
- 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
- 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
- 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.
6. Copy the release and run migrations
Install the artifact
Create an application directory owned by the deployment account and upload the release and its runtime environment file. A versioned directory makes rollback safer than overwriting a running tree:
sudo install -d -o deploy -g deploy /opt/my_app/releases/20261015-1200
rsync -a _build/prod/rel/my_app/ deploy@server:/opt/my_app/releases/20261015-1200/
Use your own timestamp or build identifier. After validation, point /opt/my_app/current at the selected release, or use a fixed directory if your procedure stops the service before replacing files. Ensure the service account can read the entire release.
Run the release-native migration
Start MySQL, confirm DATABASE_URL is available to the command, and migrate before starting the web process:
sudo systemctl start mysql
sudo -u deploy env $(sudo cat /etc/my_app/my_app.env | xargs)
/opt/my_app/current/bin/my_app eval "MyApp.Release.migrate"
Prefer a generated bin/migrate helper when your release provides one. The important distinction is that migration code runs through the release’s runtime and application module; Mix is not shipped in the production release. Review every migration in a staging environment and take a verified database backup before destructive or long-running changes.
If the command fails, do not start Phoenix and hope the service will recover. Check the database hostname, credentials, grants, schema permissions, TLS mode, and the release’s runtime configuration, then rerun the migration deliberately.
7. Supervise Phoenix with systemd
Create the unit
Create /etc/systemd/system/my_app.service:
[Unit]
Description=My Phoenix application
Wants=network-online.target
After=network-online.target mysql.service
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/opt/my_app/current
EnvironmentFile=/etc/my_app/my_app.env
ExecStart=/opt/my_app/current/bin/server
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
The generated release normally includes a server helper. If your project generated a different executable, use that exact path and test it manually as the deploy user. The After relationship orders startup after networking and the package-managed MySQL service; it does not replace connection retries or health checks inside the application.
Best Value
- 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
- 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
- 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
- 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
- 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.
Enable, start, and inspect it
sudo systemctl daemon-reload
sudo systemctl enable --now my_app
sudo systemctl status my_app
sudo journalctl -u my_app -n 100 --no-pager
Test Phoenix locally before exposing it through nginx:
Recommended Free Tools
curl -i http://127.0.0.1:4000/
A failed start usually means an absent environment variable, an incorrect release path, an incompatible runtime, a migration failure, or a port already in use. The journal shows the release’s standard output and error; use it before changing multiple settings at once.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.8. Put nginx in front of Phoenix
Create a reverse-proxy server block
Install nginx and create a site configuration for the real hostname. The proxy preserves the original host, client address, and connection protocol:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable the site according to your distribution’s nginx layout, remove or disable an unwanted default site, then validate and reload:
sudo nginx -t
sudo systemctl reload nginx
curl -i http://example.com/
Keep Phoenix listening on loopback (or another private interface) so clients cannot bypass nginx’s headers, TLS policy, and access controls. Check nginx’s access and error logs separately from the Phoenix journal when a request reaches the proxy but not the application.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
9. Enable HTTPS with Certbot
After DNS resolves to the VPS and port 80 is reachable, install Certbot and its nginx integration using your distribution’s packages. Request the certificate for the exact hostname:
sudo certbot --nginx -d example.com
The nginx plugin edits the matching server block. Let’s Encrypt certificates are valid for 90 days, and Certbot installs a systemd renewal timer that attempts renewal twice a day. Verify the complete renewal path instead of waiting for expiration:
sudo certbot renew --dry-run
Inspect the resulting nginx configuration and test both HTTP and HTTPS. If validation fails, confirm DNS, port 80 reachability, the hostname in the server block, and any external firewall or load balancer. Keep Phoenix’s private port unchanged; TLS terminates at nginx unless your architecture explicitly requires end-to-end encryption to the application.
10. Operate, update, and roll back
Use a repeatable release procedure
- Build a new immutable release on the compatible build host and record its source revision and runtime versions.
- Upload it beside the currently running release; do not delete the known-good artifact.
- Review migrations and take a current MySQL backup before applying changes that cannot be reversed.
- Run the release-native migration command with the production environment loaded.
- Switch the service to the new release path, reload systemd if the unit changed, and restart the Phoenix service.
- Check the systemd status, recent journal entries, nginx response, application health endpoint, and representative database-backed request.
- If validation fails, stop the service, restore the previous release path, restart, and follow the database rollback plan. Reverting application files cannot undo an already-applied schema change.
Monitor the right logs and checks
systemctl status my_appandjournalctl -u my_appfor release startup, crashes, and environment errors.- Nginx access and error logs for proxy status codes, upstream connection failures, and client request details.
systemctl status mysqland MySQL logs for startup, authentication, storage, and connection problems.- A Phoenix health endpoint that does not expose secrets and, where appropriate, verifies a lightweight database query.
- Disk, memory, CPU, connection-pool, and database-storage trends so capacity decisions are based on your workload rather than a generic VPS recommendation.
Back up MySQL independently of the application artifact, store copies away from the VPS, and periodically perform a restoration test on an isolated system. A backup that has never been restored is not a tested recovery procedure.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Quick Recap
Troubleshooting by symptom
| Symptom | Where to look first | Likely correction |
|---|---|---|
| Release exits immediately | journalctl -u my_app |
Confirm ExecStart, executable permissions, compatible Elixir/Erlang/OTP build, required environment variables, and the release’s runtime configuration. |
| Connection refused on port 4000 | systemctl status my_app and local curl |
Verify Phoenix is listening on the configured PORT, that PHX_SERVER or the generated server helper is active, and that no other process owns the port. |
| MySQL access denied | MySQL authentication log and the exact DATABASE_URL |
Correct the username, password, host-specific grant, database name, URL encoding, or TLS options. Do not switch to the administrative account. |
| Migration cannot connect | Run the release eval command manually as deploy |
Load the same environment file used by systemd, start MySQL, verify private-network reachability, and confirm the repository’s runtime configuration. |
| nginx returns 502 | Nginx error log and local Phoenix request | Check that Phoenix is running on the address and port in proxy_pass, then inspect service logs for a crash loop. |
| HTTPS issuance fails | DNS lookup, port 80, and nginx server-name matching | Point the hostname to the VPS, allow inbound port 80, remove conflicting server blocks, and rerun Certbot after the HTTP challenge is reachable. |
| Requests generate the wrong URL or scheme | Phoenix endpoint configuration and nginx headers | Set PHX_HOST correctly and preserve Host and X-Forwarded-Proto in the proxy configuration. |
Production cutover checklist
- DNS resolves to the intended VPS and SSH key access works for the non-root deploy account.
- Operating-system updates are applied; the firewall exposes only required ports.
- MySQL starts through systemd, uses a dedicated least-privilege account, and is not publicly exposed.
- The release was built for a compatible OS and architecture with pinned Elixir and Erlang/OTP versions.
DATABASE_URL,SECRET_KEY_BASE,PHX_HOST, andPORTare supplied at runtime through a protected file or service environment.- The release-native migration completed successfully before Phoenix started.
- systemd starts the correct release as
deployand restarts it on failure. - nginx passes the host and forwarded headers, and
nginx -tsucceeds. - Certbot issued the certificate and
certbot renew --dry-runsucceeds. - A database backup, restoration test, health check, monitoring view, and previous release artifact are available before the first update.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

