Deploy Your App to the Open Internet with Docker Using Codex on a Mac

This guide is intentionally designed for people who do not want to drive deployment from a local terminal. Codex runs commands on your Mac and on your server, while you handle a few web-panel actions such as DNS and public key paste.

The process is split into small, safe chunks so each stage is verifiable before you continue.

What You Need

Phase 0: DNS in Registrar Panel (Human, Web Only)

In your domain DNS panel, add:

Use an online DNS checker to confirm both records resolve to your VPS IP. You can continue while propagation is still finishing.

Phase 1: Give Codex SSH Access Without Human Private Key Handling

Step 1.1 Generate and Save SSH Key on Mac (Codex does it)

Send this to Codex:

Create an SSH keypair for VPS deploy on my Mac and save it to disk.
Requirements:

Use ed25519.

Save private key to ~/.ssh/codex_vps and public key to ~/.ssh/codex_vps.pub.

Set permissions: private key 600, public key 644.

Do not print the private key content.

Print only:

the one line public key from ~/.ssh/codex_vps.pub

confirm the private key path

Stop after that.

Human action: Copy the public key line only.

Step 1.2 Add Public Key in VPS Provider Panel (Human, Web Only)

In provider panel:

Step 1.3 Ask Codex to Test SSH

Send this to Codex:

Try SSH to my VPS and run only basic checks.
Host: YOUR_SERVER_IP
User: root (change to ubuntu if provider says so)
Key: ~/.ssh/codex_vps
Commands:
whoami
uname -a
uptime
Report results and stop.

If this works, continue.

If Provider Only Supports Password Login Initially

You can still avoid local terminal by using provider web console once to install key-based login.

Human action: Open provider web console and log in with the panel credentials.

Then send this to Codex:

My VPS only supports password login via provider web console right now.
Give me a short command block to paste into the server console that:

creates user codex with sudo

creates /home/codex/.ssh/authorized_keys

inserts this public key exactly:
PASTE_PUBLIC_KEY_LINE_HERE

sets correct permissions

adjusts sshd to disable password auth and root login only after key login is confirmed
Output only the commands and one sentence telling me to paste them in the console. Stop.

Human action: Paste commands, then re-run Step 1.3 with user codex.

Phase 2: Base Server Setup (Codex, One Chunk)

Send to Codex:

Do base server setup only.

apt update and upgrade

install ufw and fail2ban

ufw allow 22, 80, 443 and enable ufw

create a non root user deploy with sudo
Stop after showing:

ufw status

users created

any warnings

Phase 3: Install Docker (Codex, One Chunk)

Send to Codex:

Install Docker Engine and Docker Compose plugin on Ubuntu using the official Docker install steps.
Then run:
docker --version
docker compose version
Stop after reporting versions.

Phase 4: Reverse Proxy and HTTPS with Traefik (Two Small Chunks)

Step 4.1 Install Traefik HTTP Only

Send to Codex:

Set up Traefik at /opt/traefik using docker compose.
Requirements:

expose ports 80 and 443

create docker network proxy

dashboard disabled or only bound to localhost

for now configure only HTTP routing, no Lets Encrypt yet
Start it and show:
docker ps
Stop.

Step 4.2 Enable Lets Encrypt After DNS Is Ready

Only after checker shows:

Send to Codex:

Enable Lets Encrypt in Traefik for example.com and www.example.com
using HTTP challenge on port 80.
Store ACME data with correct permissions.
Then verify by requesting headers from:
https://example.com?utm_source=aitoolsfor.you
https://www.example.com?utm_source=aitoolsfor.you
Stop after results.

Phase 5: Deploy App from GitHub or GitLab (Codex, One Chunk)

Send to Codex:

Deploy my app from:
Repo: YOUR_REPO_URL
Branch: main
Path: /opt/apps/myapp
App internal port: 3000

Do:

clone repo into /opt/apps/myapp

create a production docker compose file for the app

attach app container to the proxy network

configure Traefik labels so example.com and www.example.com
route to the app port

start the app stack
Show:

docker compose ps for the app

last 80 log lines
Stop.

Human action: Open https://example.com?utm_source=aitoolsfor.you in a browser.

Phase 6: Environment Variables Without Scaring the Human (Two Chunks)

Step 6.1 Ask Codex What Env Keys Are Needed

Send to Codex:

Find how this project expects environment variables.
Check for .env.example, README, or compose templates.
Create /opt/apps/myapp/.env with only placeholder keys and empty values.
Print the .env file contents without secrets.
Stop.

Human action: Fill in .env values.

If you prefer no SSH shell editing, use provider web console editor, or ask Codex to install a tiny web editor bound to localhost (only if you are comfortable with that workflow).

Step 6.2 Apply Env and Restart

Send to Codex:

Restart the app stack to apply /opt/apps/myapp/.env.
Then verify:

container is healthy or running

request the homepage over https and show HTTP status
Stop.

Phase 7: Updates and Logs (Final Chunk)

Send to Codex:

Give me a minimal operations note with exact commands:

update to latest main and redeploy

view logs (proxy and app)

restart services

rollback to previous git commit
Stop.

What You Should Expect After Success

Back to all guides

Share This Page