<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.jb-vpn.uk/index.php?action=history&amp;feed=atom&amp;title=Webapp%3ADeployment</id>
	<title>Webapp:Deployment - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.jb-vpn.uk/index.php?action=history&amp;feed=atom&amp;title=Webapp%3ADeployment"/>
	<link rel="alternate" type="text/html" href="https://wiki.jb-vpn.uk/index.php?title=Webapp:Deployment&amp;action=history"/>
	<updated>2026-06-16T06:45:17Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.5</generator>
	<entry>
		<id>https://wiki.jb-vpn.uk/index.php?title=Webapp:Deployment&amp;diff=246&amp;oldid=prev</id>
		<title>Josh: Uploaded documentation from markdown files</title>
		<link rel="alternate" type="text/html" href="https://wiki.jb-vpn.uk/index.php?title=Webapp:Deployment&amp;diff=246&amp;oldid=prev"/>
		<updated>2026-02-05T22:46:48Z</updated>

		<summary type="html">&lt;p&gt;Uploaded documentation from markdown files&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This guide describes how to deploy code changes and updates to the production Docker stack for WebApp (Laravel + Vue, served via Nginx). The same content is maintained in the WebApp repository as &amp;lt;code&amp;gt;DEPLOYMENT.md&amp;lt;/code&amp;gt;; for current status and URLs see &amp;lt;code&amp;gt;DEPLOY-STATUS.md&amp;lt;/code&amp;gt; in the repo.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Production runs as a Docker Compose stack:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;app&amp;#039;&amp;#039;&amp;#039; – PHP-FPM (Laravel), container name &amp;lt;code&amp;gt;webapp-php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;nginx&amp;#039;&amp;#039;&amp;#039; – reverse proxy, exposes app on &amp;lt;code&amp;gt;127.0.0.1:8008&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;db&amp;#039;&amp;#039;&amp;#039; – MariaDB 11, data in volume &amp;lt;code&amp;gt;webapp-mysql-data&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
App code is mounted from the host (&amp;lt;code&amp;gt;/root/WebApp&amp;lt;/code&amp;gt;), so many updates only need pull + migrations + frontend build, without rebuilding images.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
* SSH (or direct) access to the server where WebApp runs&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt; available&lt;br /&gt;
&lt;br /&gt;
* Repository at &amp;lt;code&amp;gt;/root/WebApp&amp;lt;/code&amp;gt; (or adjust paths below)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; configured (database credentials, &amp;lt;code&amp;gt;APP_KEY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;APP_URL&amp;lt;/code&amp;gt;, etc.)&lt;br /&gt;
&lt;br /&gt;
== Deployment Steps ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Go to the app directory ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/WebApp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Pull latest code ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Resolve any merge conflicts before continuing.&lt;br /&gt;
&lt;br /&gt;
=== 3. Rebuild Docker images (only when needed) ===&lt;br /&gt;
&lt;br /&gt;
Rebuild &amp;#039;&amp;#039;&amp;#039;only&amp;#039;&amp;#039;&amp;#039; if you changed:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;docker/Dockerfile&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; (service build context, Dockerfile path, or image name)&lt;br /&gt;
&lt;br /&gt;
* Base PHP/extensions or system packages&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose build --no-cache app&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you did &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; change the above, skip this step and keep the stack running.&lt;br /&gt;
&lt;br /&gt;
=== 4. Install or update PHP dependencies ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec -T -u root app composer install --no-interaction&lt;br /&gt;
docker compose exec -T -u root app chown -R www:www /var/www/vendor /var/www/bootstrap/cache&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For major upgrades (e.g. Laravel version bump) you may use &amp;lt;code&amp;gt;composer update&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;composer install&amp;lt;/code&amp;gt; after reviewing dependencies.&lt;br /&gt;
&lt;br /&gt;
=== 5. Run database migrations ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec -T app php artisan migrate --force&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;--force&amp;lt;/code&amp;gt; in production so the command does not prompt.&lt;br /&gt;
&lt;br /&gt;
=== 6. Build frontend assets (Vite) ===&lt;br /&gt;
&lt;br /&gt;
Required after any change to JS, CSS, or Vite config so &amp;lt;code&amp;gt;public/build/&amp;lt;/code&amp;gt; is up to date:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm -v &amp;quot;$(pwd):/app&amp;quot; -w /app node:20-bookworm-slim sh -c &amp;quot;npm ci &amp;amp;&amp;amp; npm run build&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, build inside the app container and fix ownership:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec -u root app sh -c &amp;quot;npm ci &amp;amp;&amp;amp; npm run build &amp;amp;&amp;amp; chown -R www:www /var/www/node_modules /var/www/public/build&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 7. Clear application caches ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec -T app php artisan config:clear&lt;br /&gt;
docker compose exec -T app php artisan cache:clear&lt;br /&gt;
docker compose exec -T app php artisan view:clear&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Optional after config changes: &amp;lt;code&amp;gt;php artisan config:cache&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 8. Restart app (and optionally Nginx) ===&lt;br /&gt;
&lt;br /&gt;
If you only changed code or env (no image rebuild):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose restart app&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you changed Nginx config (&amp;lt;code&amp;gt;docker/nginx/conf.d/app.conf&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose restart nginx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a full stack restart:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Post-deploy verification ==&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Local HTTP check:&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;code&amp;gt;curl -s -o /dev/null -w &amp;quot;%{http_code}&amp;quot; http://127.0.0.1:8008/&amp;lt;/code&amp;gt;  &lt;br /&gt;
  Expect &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Public URLs:&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
&lt;br /&gt;
  * https://app.josh.me.uk  &lt;br /&gt;
&lt;br /&gt;
  * https://app.jb-vpn.uk  &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Logs:&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;code&amp;gt;docker compose logs -f app&amp;lt;/code&amp;gt;  &lt;br /&gt;
  &amp;lt;code&amp;gt;docker compose logs -f nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== When to run one-time setup again ==&lt;br /&gt;
&lt;br /&gt;
The script &amp;lt;code&amp;gt;docker-setup.sh&amp;lt;/code&amp;gt; is for &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; setup (key:generate, migrate, db:seed, passport:install, storage:link). You do &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; need to run it on every deploy. Only re-run (or run its steps manually) if:&lt;br /&gt;
&lt;br /&gt;
* You are deploying to a new environment, or&lt;br /&gt;
&lt;br /&gt;
* You have added a step that is not yet in the normal deploy flow (e.g. a new artisan command that must run once).&lt;br /&gt;
&lt;br /&gt;
== Summary: minimal deploy (code-only change) ==&lt;br /&gt;
&lt;br /&gt;
For typical code-only updates (no Dockerfile/compose changes):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre class=&amp;quot;lang-bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/WebApp&lt;br /&gt;
git pull&lt;br /&gt;
docker compose exec -T -u root app composer install --no-interaction&lt;br /&gt;
docker compose exec -T -u root app chown -R www:www /var/www/vendor /var/www/bootstrap/cache&lt;br /&gt;
docker compose exec -T app php artisan migrate --force&lt;br /&gt;
docker run --rm -v &amp;quot;$(pwd):/app&amp;quot; -w /app node:20-bookworm-slim sh -c &amp;quot;npm ci &amp;amp;&amp;amp; npm run build&amp;quot;&lt;br /&gt;
docker compose exec -T app php artisan config:clear &amp;amp;&amp;amp; docker compose exec -T app php artisan cache:clear&lt;br /&gt;
docker compose restart app&lt;br /&gt;
curl -s -o /dev/null -w &amp;quot;%{http_code}&amp;quot; http://127.0.0.1:8008/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rollback ==&lt;br /&gt;
&lt;br /&gt;
If a deploy causes issues:&lt;br /&gt;
&lt;br /&gt;
# Revert code: &amp;lt;code&amp;gt;git checkout &amp;lt;previous-commit&amp;gt;&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;git revert&amp;lt;/code&amp;gt; and then pull).&lt;br /&gt;
# Re-run the same steps (composer install, migrate if you need to reverse migrations separately, npm run build, clear caches, restart app).&lt;br /&gt;
# If you had run new migrations, consider &amp;lt;code&amp;gt;php artisan migrate:rollback&amp;lt;/code&amp;gt; if appropriate, then redeploy the previous code.&lt;br /&gt;
&lt;br /&gt;
Keep a note of the last known-good commit so you can return to it quickly.&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;br /&gt;
[[Category:Documentation/Webapp]]&lt;/div&gt;</summary>
		<author><name>Josh</name></author>
	</entry>
</feed>