From fd476feeedbfcd0c9d675a758eb47204d930020a Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 14:06:27 +0200 Subject: [PATCH 01/14] chore: move some stuff --- src/env.js | 2 +- src/lib/api/client.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/env.js b/src/env.js index c49682a..0fde631 100644 --- a/src/env.js +++ b/src/env.js @@ -40,7 +40,6 @@ export const env = createEnv({ */ runtimeEnv: { NODE_ENV: process.env.NODE_ENV, - NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL, DATABASE_HOST: process.env.DATABASE_HOST, DATABASE_PORT: process.env.DATABASE_PORT, DATABASE_USER: process.env.DATABASE_USER, @@ -56,6 +55,7 @@ export const env = createEnv({ FEIDE_AUTHORIZATION_ENDPOINT: process.env.FEIDE_AUTHORIZATION_ENDPOINT, FEIDE_TOKEN_ENDPOINT: process.env.FEIDE_TOKEN_ENDPOINT, FEIDE_USERINFO_ENDPOINT: process.env.FEIDE_USERINFO_ENDPOINT, + NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL, }, /** * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially diff --git a/src/lib/api/client.ts b/src/lib/api/client.ts index df56eaf..6e2a341 100644 --- a/src/lib/api/client.ts +++ b/src/lib/api/client.ts @@ -1,4 +1,5 @@ 'use client'; +import 'client-only'; import type { AppRouter } from '@/server/api/root'; import { createTRPCReact } from '@trpc/react-query'; From bbf76e3a87d240530ff452c718e44a5bee0f87a3 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 15:22:16 +0200 Subject: [PATCH 02/14] fix: build run by copying static files correctly --- .env.example | 4 +++- Dockerfile | 4 ++-- package.json | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 1ec2c58..f407f4e 100644 --- a/.env.example +++ b/.env.example @@ -8,10 +8,12 @@ # When adding additional environment variables, the schema in "/src/env.js" # should be updated accordingly. +# The ARGS in docker-compose.yml and the Dockerfile must also be updated. +# Also update any GitHub Actions that use these variables. # General -NEXT_TELEMETRY_DISABLED="true" NODE_ENV="development" +NEXT_TELEMETRY_DISABLED="true" NEXT_PUBLIC_SITE_URL="http://localhost:3000" # Database diff --git a/Dockerfile b/Dockerfile index bcd4f37..b2f34bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ COPY --from=deps /app/node_modules ./node_modules COPY . . ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 +ENV NEXT_TELEMETRY_DISABLED=true ENV SKIP_ENV_VALIDATION=true # Set environment variables during the build @@ -65,7 +65,7 @@ FROM base AS runner WORKDIR /app ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 +ENV NEXT_TELEMETRY_DISABLED=true ENV SKIP_ENV_VALIDATION=true RUN addgroup --system --gid 1002 nodejs && \ diff --git a/package.json b/package.json index b15b270..8f71801 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,12 @@ "type": "module", "scripts": { "prepare": "if [ \"$NODE_ENV\" != \"production\" ]; then lefthook install; fi", - "postbuild": "next-sitemap", - "prebuild": "next telemetry disable", - "build": "next build", "dev": "next dev --turbo", "lint": "biome check --write", - "start": "next start", + "prebuild": "next telemetry disable", + "build": "next build", + "postbuild": "next-sitemap && mkdir -p .next/standalone/public && mkdir -p .next/standalone/.next/static && cp -R public/* .next/standalone/public/ && cp -R .next/static/* .next/standalone/.next/static/", + "start": "bun run .next/standalone/server.js", "db:start": "docker-compose up db", "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", From 51ad700ad721956bdfb5331e126cc4878f12273e Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:18:25 +0200 Subject: [PATCH 03/14] chore: update some packages --- Dockerfile | 4 +--- bun.lockb | Bin 226469 -> 230727 bytes package.json | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index b2f34bd..a2f4ee5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,6 @@ COPY --from=deps /app/node_modules ./node_modules COPY . . ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=true ENV SKIP_ENV_VALIDATION=true # Set environment variables during the build @@ -57,8 +56,7 @@ ENV FEIDE_TOKEN_ENDPOINT=$FEIDE_TOKEN_ENDPOINT ENV FEIDE_USERINFO_ENDPOINT=$FEIDE_USERINFO_ENDPOINT # Build the application -RUN bunx next build - +RUN bun run build # Production image, copy all the files and run next FROM base AS runner diff --git a/bun.lockb b/bun.lockb index 878935d3bca70245f9c19126740f58360d8ddae4..327f8083d0b568d83f2587449f0cceaaee6d1c19 100755 GIT binary patch delta 37547 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

Vbdt(cI0$Qppec)BwknuOWr38jUenJp^StR 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 delta 35755 zcmeHw33yFc|Mj^?F1bpRLrwTRG z8e1(|RA)n}(m^OiOR1sXTIcMYo2ImV-|zo_zUOi(9-i>a@T;*hZO~^A-9DOK`=00On}sJkqiXMr+OfXf%GcJH8lF$%r{L_Uih7)V z%jgC9($jQJdq&eT294;Qn1Hw;se^{lr$Q}FD+2wtkEWFaPw~~XLg3`S$^B9hU#PaG zIbaWlUKCugfaTu{HuL)g=_-M@fh&R+$b80tE5MEdSJkxij9>)lSVrrPFp0v;S@`TqiDK4-w}_(Nb%a9mT%e*^3??6|oIFyrxH7Nj-D z$bu(m)(G@YO&y+=(pNhOog=gvTnrozW(99Hv-ES|Qm}`&uts#C$FAk0b zGyf2s`FGYbQih}sMVNgP! zzD1xj{exCUl>#-2AB(WEIcu}ZO>JXzFA$VoqpdYOPwV%*{hPPnRCg6cKJ2!$kyban z17`njP>g1>+4EqtThhVsPtRD`$?C5=VD`ti;9_9aKTjLb`Dh0xN(Pt(uj^_JaNdEQ z0i6?i1epG6T>HW)XivPgL{qipag3kRE@W~b0%yytU8$W zOzmaa=fKRSxb&aY+bXX)(s3SLjI->_KGp>M4NU+0(Agn-W375>NY8#~)=$%_v4gUa z0UbXDmj)k30&no?{?-CI0A|CsBc2PbFqj!`gdZ!K0OpMMht7iIp99p zT8gQ|hYcQ)tZ8H5SP_0P;0oXtV0L{za7}PF(lMWRz_eF_=|2u!1N_E|*3fi^%}q2| za_JcKKU?tWIIBf>dsvg{0+5-N!uID&8Q*LaVYx_8iMtrX%8n`{>h1h6H^jWQ=_I>yX6_^4)_&H&y*)X zFelY18Swx%=fDjxGyY+!mEbL~2kbeoT09vx$G++`Ym7a?+&$YMp8R*|(p7@T)2#}q zga=U(R-occE2ENrNF6e2u%>O8YZbI= zf|YTHc~(5mDL6G~+I;BrSLc~mU~^8SB_t2xkc7i##nQkYJd?j5tPBUrgqLBn;1mup zKJn1ml^tb#_yps(LKXBT6O6KjD^v+sWEJ-_m?NJsI4wD0c<%uT!}>F^_Ur_sd*Pt; zT1%}7RUFJ+?(q`Kz5=HGnY8yydn33w^aWC%2xco%!0fFzkTqMGoRH!-q*s!*b-7jP zWzbpK*(D`96a6ZTE*H6n3PAMMB*D}yayR`4~+ z6D1Fk+#SpcwFGnX36xwxvWLmoX78@H94<*dDfunQYr$;cT*>1l50)GQW`!dphe)m= zc^n$X3M7Ns&_6T;%RJ+MrX~MfL+Y|+|Fk7Hvy8WjR_Iu5hqbh^SDCwRJ2~WU?zFb| zd0?)jv0$EW`hdANE>;WYyHPKt$v-hE@x< ze+|puNUj#D`_(e8Hgnnw`D$7h<9f4DeV(t8)ZD3`^EEbrO4l~7f;!YTe4lgbvuhhk z&pGXdyQ7Y##W9(E075;@(0d4(S=r0_X<83c8-Y+?GjtXqD@DV)DzpG0 zEA1VGqD{Z{&#KT`gsfb2e@%-rW1|u3#E`zx-|%hav`<6Zx)^?~Lhaum6laE-)?>ER zmLO!s-bSd0skN)mDlv8|LRN}m4OA!vAuH_(grZHq8bKmYH9dY4|Nm^)wHgbmv6A%Kh*GT=hSzH8cFS(jsnO!!i>9BCD;+wSkscM z9700eVc_C`nfnGinmDn!S=N9McNo1aKc8Sn)h3$OBFC{mten#9`(Sl8k{gA&H`TQE zrqiv!5E?QwWPK4bew{S z9>lB+@DJAWKWA)+bn302Gp|Zd!eo!jjSr6j&TT~ zmry`}U$A4Bw9NMEw^|rUot%zV&uhHtk)4nU%c{drpJ4sV=MCS^PCdS*k<{5~7cJq* zCE+-O5XZrdOU2>S3gZAvW4#?iU@-?bBOowX&uV3C=;G7^TN_uqI32T4M~<}B;m2Wx zz(Ui|Ubk>#LszHXD%`jVS{QElMmg>0!qIVtUsR~>jG&-rL>O10|9}x~Wn70|w~dk1 z&1rw7jixm-lDmaE4kIM{+CR8fCW0MN1~!~Od{Uv8hJJC>iDU8m*2Ne_t9jNcg*^os z|1;+}I5THvi~T0&^Q4>|Tj0!2E^Y+W3)X*bXZUt^+Wj!}F&sX7CPE#ItTv(cGYDZ$ z$A!7QfJtWf#hZa7)9Y(Uv1X_-I={UcdKIB~h8))rV&&1d{=tq0k;)o6A;b+vBh$SK zYTVvPP6%@|11x(#LT$}Rk4~6GW?mf;!Z31PHV<~JhlK@(oNqM_b`Q(-EFvWnj)%$68p8kR7ag!H#cWaYf`adq1F; zHQcbUYrP6f#=*J`i)-GBYuY;}PmJ2@usElzxLY}K%q6&wiW}-1Y+nVdt8qO!%)M{! z?BZatEpEn^Knxr#j03Ca7i@n7tA*h=ILy7Drs0~EGWNC;u&nyfD%aoYK#V*_w?8a) zAWn(c#qPqwt%|fdA`7do+?ZAkFg7GQ9aR&p^38LoBN>*}aAv&^76ur}S+^2N)|P5j zVkj(GQ+U1y%ayLwKx-?t&dVcUwKuL~Z~Gb{t8(Zbd+;Ehtg;eA^~HmXq(M%{#}F`r zEDpU_J6UBy=T~7x(%F%XkUzW}JO$Xj26M79^A{1~PGwbZ7c5ux3J%Gs9`?H)u(-4> z&n2*AuOO~Yil$+pWF2O~k{y6Ld=D#zW!d`<)wF(Qsox^xO5JLhwUgq!SS?teH_X_O z;&glhkrgvVN8wbfaP04xgdJdYK%8!F%gbPKU@hwgEF_iHj2~{D-tw6X{2f>!rspl3 zJ${1~Ze*o|>d%cZt`2kBmyXc11Pb=w5qiP!>l3QCA8BkzbvllWw9Y%`e6trB#fyln z)KGowC?jdO(|!U%CoyR0+1f4ht7N!$R$k5yCY^pHO>` zG;@SdiH&K7??|V;+!!-&R3ZhTA!c>HMhKTBBSY=Z7d0)JA;&(1nj&knf9#K7^*25G zj8&lz5$bI=;^81b#psd>{u()FJVO)$-_e(bu+9v zX6aL4C7Ah?9M62%qP_^3dFva;8&}6T?WJB;P9qWO&Cao(F}3SsLLH4>v6i2ip+4yq z!*?vMfgtjXiopsA)-O#kHjH)Zu@jA}h}%5Tx;#L?VyFHNRvma^Iz)uHP2#SYj9vC6 zgo4ZraCP9=P8}95Gcadv!)gu-BZv*C{$#ZmV#m;DOg65*ge#~i){c*hi*CV=cvvAw zP{0`4DA=(87S9bH=A!--RwGyr?ksliO!T3V<%=Oh2wP9}Prx zX2>|C!BjpDtF>``a+v!}D~Yuc50F*?bI1J%RvGM!OJVjm*@J`>=32=Aa}7 z+hgZ(bhB!Pxg)@3ZB_dsWy=W{<<;gJSEo81J?2}R5(WcpUk?j6S)Fi2i4doNm9&Jg zh6Qaz(imZE@O3(tLVO-BMa;3fE?scpf$iOAfwhfW`(QLIYr!y1z+yeDtk1z>LAVOQ zg@xSXMXlw7OEpVG1L^uVJ+{b4T;+!T5Tlp^-Hw%(m3HI;RPaz6Os;IKFOdFq*i% zZfT88$g8WF4MGjX6QwPupL4>ju19}gvu>9Z{p^JItC-eMxvWgjlHnA$5;)y z4J*vF*voZS7#rp}^>r(ZtDurA4d3}rN1v7ImW6|~5mvZa?*NQ=fmO!U`A$7?mEkL# zj@7HI(XnRkja9}5;j~{^!y09YP`lq+)|a6%IiVvtp_1!VYyv`UOuvl?;S7fqcXC3` z_0+D5FgG*6$Wu8XuMH|eubj{uR%mgU8v?D&+(O?_p_g+)$8thNH)8&peqC}xi*iC= z=Y*{8hWwU>x#dW|9avc0xKF&c-AG#H)ctoD8&)|TLw8tL zX1MpnspBN9P75&Nd`cK#@|G!9Rep#n^p!w{vXV?u-VOFdt;`4(`gK3uq=L45#|Km@q zz=Pxx-~iZkYyhTX2-pMMT(?|zy*+) zwg)qj%zTQ#_5#-eGs+i-bO!3+z%i-^<|GOQQ*SKw7Bui7b8<$33xa!rOM^#)3xOws zi-QH2`MeIspSB!_M&NT`R_p?p75`dC`|0ov4&=*{zXQ|ZdoVM)A?=^Q%-}YdE&5g3 zzsdLqVEk#1aA3R+XZqW5V1D_*jCYrM!F=d{PPQU4qL}0oVD?B^FvqZx)T>C{2aG?h zj@0W)_6M`z29g_rS#YSdn}YcvQ*V|o1I@u4yEf8+%wT)Tkzm%mleD{nS@G_YV`Y3i zm>DO4@u&5X+#gK;fzlofW`5}@Qb?7;2+5neZ@}86N{P>NpN8;FPpKmHdU&&w^Rd zC8>WW^=vSQ@+SBh@Ix^3wIQ=wTz@`h0OwRN;_SRn_2MJGM|ewp6ta0m!v>uO|O9S8Rxf_;q26YlCim&+1;cU_-8QfU!)(I`mfS{ z60_9%GM-HThhXOONb2BpQ+Op@ zngJIx;u$zF!y;fe0eIz=Vngqs!}J@ubSlQcFtma z5HRaqQ#$5mPPoQ0zKKlORB|)P&B0vSZNdEfbGFL=%LMF^4l?81OuaL7_G?!#TNWk# z$kd}H_mFySX2XW2%ZQ=>k2wARreL-(6%{W7o+=ygA9DJCoA7@q9mbzE=GeU|TR^5g zP1LL4U;w{VS$7Pvu3c89Q8?4i)w4xzjQ z!WNO}fN+n(2@2bUmj{G(`5}z+fUrXxqtLAY1iyk1c8Rot5Zv7%oTsoy_&ft)H-+iX zKzLi6p)kM!p>ZJy`$T3T2%a7gu2VQ58Wx6dl){q25DtlK3Zn}`XjcTnyJBGx2(_Mp z@QA{DBD^Ss(-g9bLO3GsQUhXu7<)#SBB88I)r>;VRZ<#sz7)|!7jpUKsZey zs|JJu;y#5bRU!1O3Be)O*MtyK4ML$>5DJRuS`e;K*his|aQHx2P#vLU9|%Rn9ty2% zKq&7Ep_oYYg>a9;2?`~IS8WLEYC;%S8$u~@j6%0s5d7*uC?nG9KydegaGrvf@bQDN zo5FNI2<5~X3Ilv0G_DJwyvVEz!Lv4m>l7-AhR;GcN@2;f5Gspo3Zv^lXy*^1s#xd` zp_U(nM--}y@Bj#>DP#pes44DKm{J!)&p-%1VtpWlkY^zjst2LAh^`0W3Wa?X{Dh-E zga!T(lIufwR_vkBIsiiX1`q;7Vgm^GD4d{BPk04ESQiLkTo8l?;uwW)^&t2KLkJdW z!4TZ*LpV>Nq3{WTu$#j45D1~-421y=AT(|Wp|Qwp2*EQ5!gUHwM8if9j#60C2tqTF zO<{B}gm$42o)Zg0A=CCZvvAP%yOP+_2AhIcpZVsVcO9;Ki!j=$fJqO_tg}x%Z6@=3ivRXmtFYZ&A(gH%y z)({fK`qmIao`+B<9Kt{m9S-3Ng?$u~g(CvOf|d}HBOnYBdnmMS1))4T&^A;gvW533 zoS={@yxKxo*BZjOwh%^$V-&iDL-1<{VU$Q~2f;l8!g&g5!lyli-4v#`hw!2}Lty|H zY~vRoj1!qJK=5n};W~wM(Xa!AqZF2OfG}QUQyAS2Lc2%^uZV?_5NfrD@QA`h5#ABP zX$n~#AxswcDNK0*LeEYRGR68%5JEaYDAXCkt0KBHgew&GQJ5|qT_7xogpk|?!c4J; zLhFtY%6Ek@TO@XcaF4Cq5g6K5z4=nA26cL+;FW_JjlQ4p?EcwIE?0pTcxB|RW47ugg>cZ1L_2Et0Q zFa|=cXb6uetQO%tA)Ka=)f2*6ai7AJ?hty$LRc@>$Kv{BgRsSc-Vo6sais^M_r)PP zOE}^oEQo=S91mf$*h8UpPYC4`AZ!td2@vj4I6+~X@ahF&T`Yugy&&um$0&4*gW%U2 z!Y+~48-?u_ACvY7pFW_s#CX!%;tXl82uU)0(~f=LE=h3RBm4qDtAIS20}k6 z5=bA3J)~2j*dWlyB9ZioI7IqXcqM~A6GKU#i({lOMCHMtFGU*ZwD_2GM)(W?ofYFr z=foM(S0W$>&{CO@!=v*d?15%?nbkxfh` zKemZWIjMlSPjVNL=^%$# zPx9Dh%dp`eXf<7JJ7wEB!Pdt%f2GZBSKH~f!@B**^LWxm%zoL{->6j0t+e`|AbJl< ztecc-{le$nde{6}w%7vpuafa7$*#ynwpKcwJ^GDKNf?HI&tGQruJ(&;74qpXP2M$l ziLJO^Xva+R*UF3oU^Dj*nLxxWv$@+#8+bs4CC)UphtyW!ab6GRT)<}LoRl~`k#}6B z7VfIB!q(AduZ@RIpK&>ej8(RE_RFh~6UEDBDp6^*&0W8|YFCA|w&uG1Jv^`HU^(yZ zs5HUM{N7u+a9KP!LsdLQ?DbmfBrfl@mP zjkkgP4K`G2$E3!`ZI+7!X0gI5Li``W1oJTWnz# z{K1up96g*RB2S`~yZ%f8454S)Qf z547(@vl4oVu0P1A{Lqn7s}9_N#$*m?%$84zWJ9Y4=7U+(Y64fKR#0m9+!4U1Rxz=m zgnmOzE2CGc&L30x7}_p?Kb}Vd9f3{&znN+Wv=^02>E+T}BNz@u0BwM2NHPQ9!vM7a zAHWx=1NZ@T0ZvMPAOPTGtPeB*f`DKk1ZW5}0yr_l06x>jnYa>I1*`_v=y-Z{EduL+ z^}q(;4PYaX1#AK~18)LbfUUqbU^}ow7qO-E`RROkYyq$kSOoB)vPr-cAQPAhyb4SM zrUSEp*}xp22hav63U~r#feJuHfY1N&nLs{}I0={xOaZ0>{O$8ybb2rTp466eilYuEfCcrPrxY)V?Yv9XARNMeN zz~_IC11Er!z(>F-;A5a1;=O?iKxLo`@EX$N>3D4^;DlWQC=C<^_{fTb&w=n^Bd*#l zzz)pCUBKG_pMJUp+y;IIegW?bVAc~A~ zx&s9OK8wT$p6&sBzUmv`0>Edp_&nE2_`d4B6oZ?ed{Mq6Ta2?>&S$tB9&u&jgVf9eKOz<-R z&k((#zYLUzjuW8vI>1u_pKaQTblm4F!LPEd52hgkRe@?ib%2|DEx-rx1-PSg2j`AG z78#8L_z(}DIO0~#eU%uG_|8B(APi^>1OjDj;zmimY|fX>VgBYX(prhEW4pBdf)!~$HWkAX+PL*M~$5BL@M3E(huG(HAC0!{$O zfe(QXfc-!iz;%uhDXuL-U?GqS3FG5Q9u76kswi377~>0A2w& z#N&Ys08i^^F995#kpM^PMPLjt3K$Kf0R?km0m1^956lDR!hF4=UcG4E#3G@R?k!>} z=^fG+!;hV@3gEP2eQN+*r^|rfnXxS{-$JY4ypn`z|EtT z47>}x1Ee>_;Sg{DXa+O|4gz#K1{?+61C9Xi1I$1z1}+3iyY z{?9Ga@q!s)Z6SXw5sB=XVXm~cZ->Us&(EP=kDGojk9XZpOzW&WE>}}>KSVyqW@W2 z)?CiWCr(KA1Y4h{_J7EX>F)!qJX@N#@+_FWq#D7VyT+5&jT%h=Kx-c_yeIpBcLG=0(b+#KoHOX;3W>PpLp5B%b%J6 zFNJtX#7m|%B$oxH%x zF)ypasB>6ySDH5lDi7+pE5&;kY6{GUm19qo;`lQ|HI{U$DjjlHKz0AqwA@2f8|itS zt$bD2GjG3KdR>M&{)~85MsVzD2Y@-t8CDt5<^?#ldXno)&h3}G5NnoOlbo$qL&XWr zMyKa(84F<-sY1EqQKPN8QrShJv0yGyYAk?v2`a5Q)1}RZu|Q5#Rc2GJeu5j5_?9gIR`Zl**5B{v3a9B+Nk7n$Eeye--yMKMrRb zfO+Na1=aGL;pP0JQ{F<@BdRx82y4w6$AEhP-2wjd(XPM?0Q2CIWN+kNy40zuigrM_ z6VMTe1k#)0z%7{DZY!WA&;oc4U}E-;+Gf=j%WaigY7L+okb9E-hdXKdAGT7}J*tNP z`<0XH|DWvhs&eeYobf}?vMamf(s<9TmMMpf=msqcP{WZkL~8u=jvL1&cQ5>J4NtmS zGXF^r{HYaap_-WgWKyyRnFr=kx_S0v>$w6{WzT@!x$_E4;%rG1IK_5fe(aNp#E&Ymk53V zd=7jDdidJ_1exCxA!5cOorNujjal;7`B}aXmnXGmwI}EK z)!pavQ12dS-_-A1rSy~;u9#pS@tA3&e9WJHGSbe6-55Ijm1kWZ>V*ai8x?=QOw6le zT`>!MMB50|OuYi3)|C=Pt~~E~+vV|zkI0~hddb4wriI_=+H;tn%cGaC@Mxz8>VxsW z$+XiwORCo}OfI}{!h-|zF6g$Gd_~DNdL_M3Z4uN)@26+`i=}N)u2I{_Ns0cYU|GJcb5}oAA*8QI93H)4%Y3H`x5yGvn<-ulYnB zz4Tm3n=fW5KgWYbOnc<@d9WDSUJneq2+u-j(}=`PpSF6w2Vapz_v^7FRofk0b zK_Mdk1>_L{&rMw7VCAXm%mdwwPn?V?+AdDq>bNx2mB;W9v59Fj;o*t2_WltA zzb;t&8>X#ird=*$!i#8gI@H)QlrjEwneUzu@epbCPeMfL4tfi{QbQ5b0duT!BT=-A z?kVPX(Ch0{8;MhqFuv`e$Lk9kiT#N2SkMUVLTNHmztc#(9I3a+qr2?Yp`t=ZloS~z z4h{#abTMIK5Oi<#R*ZxR@3vVxEUq;746Bag!^E1n(OlXB}}ByL%rl- z#i~9j@4r2|xaH9Rr3Ew=t2*hiPwk0AjYZSWf6)`N<$uv)S=+y;rB#Nf{<>4dcKMI% zqI%yoI%+ijX~}_NRu{d_)4JdoJa-ejrvtU=czMmhxxF@b)otexV-1{sudSGrfS#6P zCk`ecM=SfBoZMATW_jY^U`!lYh=+=@+SY=4hyHqCj*hi9Xb@_8Gg&Vy4tCay|H(u3 z3da7_Xjk?BF zsH?Yn$IaefSKm)N8=d9K;hjiPsUN!fY@}$^&sEo)I#_iJG#i>D!r7xgP7iszCQmQt z_%G}v3J<_C`?iya8Gyp>bP}_2^AiinGsW^Y4O?A&;u9+Tr{T$|#nWo1PC8)Pf zbS<>qcSQqVMPBr10FTl!ViWSvgJVS47CL@p>V@sn=u-?r)aHiddx8_r{84Stv!l%d6b}w#6?y^y)LYJr+Y<*uK#_6tFWd>TN%~(rNn!eFHZPc$QU#s zAx@l{h-!?D6R|77bK}IaN#KofV(d8ZVdR|&z8ELoqLbb<3-A3us`fo z;O6n7&MV+9@uKZZ;1Tg+EcH3@B7^q!c=0A|?@!~+|7k4azTfK0iL;V>sNgAzngIyQ!x3F6>**j5b!Mbnu$?@2>X?Imtz;AB`K z1LC<}V(CH{5wGG($aIsPp3^GT3RQcV+dof@v?_Zt>CXMzY^Hjnb)$xIPvwk9;1E6wH zIV)QYsIm|A7c=I;|8)QP8~>CnP-PSJ^hJ;_(fU56PyfqVYgfPVv)MTF3pG`gD&miG zCQw&%Pt7$ow^Ws_k$@!_qPqJD?s>z;eq2x^6pN5DI)383(D+L3GW$kYFV8&;znXgK+ z){0yK&4-FvGhNfi+kE37W_-}jZAXVqp3~V(Zti9(dC)M?0gE!HVv~A{FQ#KzPaGyH zErR}bPm!@&uV*v&mq2Nn^>4ZvZdh_>XMnM`3(w58VDeNXXO89F-&DWl?P;}dsUFYU zkMf+M22Qp{jGc|KK$V-W(7miGTVtI^(?5+D_2*!2KK(Q%3sCjjHd3T;cByWYds&`w z_xy{UO0~q=T5@K-s;ViFRWQtIpJ*J z0oNs%Y{FAUHfLr2abY~QygY-aCh8yClG8yViP&AF69S-MW&~<@K8P z|Ib%tYG2GV9)Gc`sJnxId;Pz^7FNBE)zEe|RzsdW!CSq>_UF{>`J4M@%ODUoW}ZBk9vM*F8P4^xHpqqjasUI zy^#MH`=|TNqP(dJVz&Q$M*TaJ{_khfUyq?YF$6vR#PGj=LQr#E)->;}o0@&<1ef<} zMBPN>X{b7{{Ihk@!sD}7@I)CdXrG-RitfX`{bj~M<| z8~sMrtA!?x+>4kXD`wRM;lCRN%-y2b_x74-{VMWWsa;pgPTV^XZvOZw2HzC;PZZy7 z!PQQ~iNbTM-qu^aTl#8b?-x6~S_@ymz!Og_;32z7B4aBSw|bj&$ILG_Rp=Js;i`5~gr}1b!|scU{H$Hi+s6vwe`Zp@dfmtrKcZ^h>Rs3C(jE_~ zx2zogeZqhXJm5kw-*Pz({1i*-DW`HFUD_86$f|do*mA>W-)!D z-+gCkk!5z>b{I-2DC!N^T|WJ>+L$3l@!eT$i1h=A+pE@ZVgVkvuKBhs>89ImB27u8 zY4fVs%W@~f=1*LY2HD-l3P*QRFm;PbyMoD4Y7EBISfs@9>U(Kd9r? zi2FaHNPp`aMbBxX@J_2pc9*w$n|Fto2JQW7%eIa1#J7p)ajoJ^5wjDsb; z+AMJaDZSNey1#jRVpFa9g%%(Mf4oFP7tR*(yY$j-{@V80qRuY(%6EHb#E17TSS7Oy zyRDwpZI-WRkb0^2%A}Da(jNCH4-b6zjW6)N>>i}VkD=}NpcgI+F<_5= zQV&=pLf(Ro&0)}6dOvUV4(~qGc6LqtYAL>yG-ok-rQ?KM*gm{%YEzM$jHht!#f~F4 z5ixDAUe-Gv`vo4e%$PbXXtQB7>-lT_m z{kgdINx!lAHh$sCW9xG9?S4JOJ9&k*#1qR$1Z_M0pt;#?{Qg=Sw?bqbKn>L^%?qzR zzB*Ez?`4io1AaNF-f7-`|JEiW(;xeoY0bUYeWf^ww0h^2;>rPx^qrN$`ylG0-gZ9W z_Z>?gc$ONB6r9Z{EpC4U;{jZlJ#wB4d7-Km7Lc zCU^0Ol!}R1EtWEEjPwX&;%J(=pIj|2FzqEdX76Y>TGhzbo4V3IaWu`e9&1FM!>Cz>HP(#i zRr;Z$NX3$OU1`K3f6qVe=k}8!Y32N)LiMx{(uWu55$Yd^_mZQ bvrX}XZ&`&E8ouk&5q)OOT_4`o$Ikgb)tVuM diff --git a/package.json b/package.json index 8f71801..eb8257b 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "drizzle-orm": "^0.33.0", "lucia": "^3.2.0", "lucide-react": "^0.396.0", - "next": "^14.2.4", + "next": "^14.2.10", "next-intl": "^3.18.1", "next-sitemap": "^4.2.3", "next-themes": "^0.3.0", From e046f986eb8a4fd81eb787250e6b90f0e30a849e Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 17:09:49 +0200 Subject: [PATCH 04/14] fix: docker envs --- docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index dae14ff..0466607 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,6 @@ services: context: . dockerfile: Dockerfile args: - - NEXT_PUBLIC_SITE_URL - DATABASE_HOST - DATABASE_PORT - DATABASE_USER @@ -22,6 +21,9 @@ services: - FEIDE_AUTHORIZATION_ENDPOINT - FEIDE_TOKEN_ENDPOINT - FEIDE_USERINFO_ENDPOINT + - NEXT_PUBLIC_SITE_URL + env_file: + - .env ports: - "3000:3000" db: From 21cd3e957eef3b96c73cdd66d22f12ac52998c35 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 17:17:29 +0200 Subject: [PATCH 05/14] docs: add info about .env to the readme --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ff10aff..5cc0a1a 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,9 @@ You can build the project with the following command: bun run build ``` -Then to serve the build locally, run: +Then setup environment variables by copying the `.env.example` file to `.env` and fill in the values. `.env` files are used to store sensitive information like API keys and database credentials and it will not be committed to the repository. + +To serve the build locally, run: ```bash bun run start @@ -113,7 +115,7 @@ We are using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0. - To keep the code as consistent as possible use functions for react components or hooks instead of const variables with arrow function syntax. An exception is when using the forwardRef hook or when creating compound components. - Only use default export for pages or layouts etc. since it is required by Next.js. For everything else use named exports. This is to make it easier to find the components in the codebase or change them without ending up with different names for the same component. -- Use `type` instead of `interface` for typescript types. This is to keep the code consistent and to make it easier to read. Aldso `type` is more flexible than `interface` since it can be used for unions and intersections. +- Use `type` instead of `interface` for typescript types. This is to keep the code consistent and to make it easier to read. Also `type` is more flexible than `interface` since it can be used for unions and intersections. ### Naming conventions From e6ca42f088c0ef6d5f1b84fa9fd1c4a2bf3af904 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Sun, 22 Sep 2024 23:29:53 +0200 Subject: [PATCH 06/14] fix: dockerignore and unneccesary specification of .env --- .dockerignore | 12 ------------ .env.example | 1 - .github/workflows/deploy.yml | 24 ++++++++++++++++++++++++ .gitignore | 5 ----- Dockerfile | 35 ----------------------------------- docker-compose.yml | 19 ------------------- package.json | 1 - 7 files changed, 24 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/deploy.yml diff --git a/.dockerignore b/.dockerignore index cfabe27..0bd563a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,26 +3,14 @@ # next.js /.next/ -/out/ next-env.d.ts -# production -/build - # misc .DS_Store -# local env files -.env -.env*.local - # typescript *.tsbuildinfo -# site map -public/sitemap.xml -public/robots.txt - # docker Dockerfile* .dockerignore diff --git a/.env.example b/.env.example index f407f4e..67a64b3 100644 --- a/.env.example +++ b/.env.example @@ -8,7 +8,6 @@ # When adding additional environment variables, the schema in "/src/env.js" # should be updated accordingly. -# The ARGS in docker-compose.yml and the Dockerfile must also be updated. # Also update any GitHub Actions that use these variables. # General diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..2206742 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,24 @@ +name: Deploy + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Executing remote SSH commands using SSH key + uses: appleboy/ssh-action@master + with: + username: ${{ secrets.USERNAME }} + host: ${{ secrets.HOST }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + git pull + bun run build + cd docs + docker compose down + docker compose up -d diff --git a/.gitignore b/.gitignore index c55f229..b8a2932 100644 --- a/.gitignore +++ b/.gitignore @@ -3,18 +3,13 @@ # next.js /.next/ -/out/ next-env.d.ts -# production -/build - # misc .DS_Store # local env files .env -.env*.local # typescript *.tsbuildinfo diff --git a/Dockerfile b/Dockerfile index a2f4ee5..b6bf37f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,41 +20,6 @@ COPY . . ENV NODE_ENV=production ENV SKIP_ENV_VALIDATION=true -# Set environment variables during the build -ARG NEXT_PUBLIC_SITE_URL -ARG DATABASE_USER -ARG DATABASE_PASSWORD -ARG DATABASE_HOST -ARG DATABASE_PORT -ARG DATABASE_NAME -ARG STORAGE_HOST -ARG STORAGE_PORT -ARG STORAGE_USER -ARG STORAGE_PASSWORD -ARG STORAGE_NAME -ARG FEIDE_CLIENT_ID -ARG FEIDE_CLIENT_SECRET -ARG FEIDE_AUTHORIZATION_ENDPOINT -ARG FEIDE_TOKEN_ENDPOINT -ARG FEIDE_USERINFO_ENDPOINT - -ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL -ENV DATABASE_USER=$DATABASE_USER -ENV DATABASE_PASSWORD=$DATABASE_PASSWORD -ENV DATABASE_HOST=$DATABASE_HOST -ENV DATABASE_PORT=$DATABASE_PORT -ENV DATABASE_NAME=$DATABASE_NAME -ENV STORAGE_HOST=$STORAGE_HOST -ENV STORAGE_PORT=$STORAGE_PORT -ENV STORAGE_USER=$STORAGE_USER -ENV STORAGE_PASSWORD=$STORAGE_PASSWORD -ENV STORAGE_NAME=$STORAGE_NAME -ENV FEIDE_CLIENT_ID=$FEIDE_CLIENT_ID -ENV FEIDE_CLIENT_SECRET=$FEIDE_CLIENT_SECRET -ENV FEIDE_AUTHORIZATION_ENDPOINT=$FEIDE_AUTHORIZATION_ENDPOINT -ENV FEIDE_TOKEN_ENDPOINT=$FEIDE_TOKEN_ENDPOINT -ENV FEIDE_USERINFO_ENDPOINT=$FEIDE_USERINFO_ENDPOINT - # Build the application RUN bun run build diff --git a/docker-compose.yml b/docker-compose.yml index 0466607..50e0d20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,25 +5,6 @@ services: build: context: . dockerfile: Dockerfile - args: - - DATABASE_HOST - - DATABASE_PORT - - DATABASE_USER - - DATABASE_PASSWORD - - DATABASE_NAME - - STORAGE_HOST - - STORAGE_PORT - - STORAGE_USER - - STORAGE_PASSWORD - - STORAGE_NAME - - FEIDE_CLIENT_ID - - FEIDE_CLIENT_SECRET - - FEIDE_AUTHORIZATION_ENDPOINT - - FEIDE_TOKEN_ENDPOINT - - FEIDE_USERINFO_ENDPOINT - - NEXT_PUBLIC_SITE_URL - env_file: - - .env ports: - "3000:3000" db: diff --git a/package.json b/package.json index eb8257b..fc02ee3 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "lint": "biome check --write", "prebuild": "next telemetry disable", "build": "next build", - "postbuild": "next-sitemap && mkdir -p .next/standalone/public && mkdir -p .next/standalone/.next/static && cp -R public/* .next/standalone/public/ && cp -R .next/static/* .next/standalone/.next/static/", "start": "bun run .next/standalone/server.js", "db:start": "docker-compose up db", "db:generate": "drizzle-kit generate", From 943ec5a9ff778af263ece9e1820efc9725a0ba2c Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 00:53:22 +0200 Subject: [PATCH 07/14] ci: setup postbuild instead of handling it in Dockerfile --- .github/workflows/deploy.yml | 3 +-- Dockerfile | 3 --- package.json | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2206742..60b8857 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,8 +17,7 @@ jobs: key: ${{ secrets.KEY }} port: ${{ secrets.PORT }} script: | + cd ${GITHUB_REPOSITORY##*/} git pull - bun run build - cd docs docker compose down docker compose up -d diff --git a/Dockerfile b/Dockerfile index b6bf37f..b16432f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,14 +34,11 @@ ENV SKIP_ENV_VALIDATION=true RUN addgroup --system --gid 1002 nodejs && \ adduser --system --uid 1002 nextjs -COPY --from=builder /app/public ./public - # Set the correct permission for prerender cache RUN mkdir .next && chown nextjs:nodejs .next # Automatically leverage output traces to reduce image size COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static USER nextjs diff --git a/package.json b/package.json index fc02ee3..4b7093b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "biome check --write", "prebuild": "next telemetry disable", "build": "next build", + "postbuild": "next-sitemap && mkdir -p .next/standalone/public .next/standalone/.next/static && cp -r public/* .next/standalone/public && cp -r .next/static/* .next/standalone/.next/static", "start": "bun run .next/standalone/server.js", "db:start": "docker-compose up db", "db:generate": "drizzle-kit generate", From 581bf36c7844d48c76ad6a0747b5a73495111139 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:46:40 +0200 Subject: [PATCH 08/14] docs: update form library --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cc0a1a..ddba536 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Here is a list of documentation to help you get started: - [Next-intl](https://next-intl-docs.vercel.app/) - Internationalization library - [nuqs](https://nuqs.47ng.com/docs/installation) - Easy to use query params - [BlockNote](https://www.blocknotejs.org/docs) - Tool for markdown textboxes -- [Tanstack Form](https://tanstack.com/form/latest/docs/overview) - When we need to handle form validation (shadcn/ui uses react-hook-form. but I think this is better, we will figure it out) +- [React Hook Form](https://react-hook-form.com/get-started) - When we need to handle form validation - [Tanstack Query](https://tanstack.com/query/latest/docs/framework/react/overview) - TRPC wraps Tanstack Query which is how we fetch data from the backend #### Styling From 09d11126c3f1c7b25212772a320ec9a4a89a48d3 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:02:32 +0200 Subject: [PATCH 09/14] ci: create deployment actions for dev and prod --- .github/workflows/code-quality.yml | 2 +- .github/workflows/deploy.yml | 34 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 2b21c9d..16f4c25 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -23,7 +23,6 @@ jobs: env: NEXT_TELEMETRY_DISABLED: true NODE_ENV: "production" - NEXT_PUBLIC_SITE_URL: "http://localhost:3000" DATABASE_HOST: "localhost" DATABASE_PORT: "5432" DATABASE_USER: "user" @@ -39,6 +38,7 @@ jobs: FEIDE_AUTHORIZATION_ENDPOINT: "https://auth.dataporten.no/oauth/authorization" FEIDE_TOKEN_ENDPOINT: "https://auth.dataporten.no/oauth/token" FEIDE_USERINFO_ENDPOINT: "https://auth.dataporten.no/openid/userinfo" + NEXT_PUBLIC_SITE_URL: "http://localhost:3000" steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 60b8857..c77af87 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,13 +4,43 @@ on: push: branches: - main + - dev + workflow_dispatch: + inputs: + environment: + description: 'Deployment environment' + required: true + default: 'Development' + enum: ['Production', 'Development'] jobs: - deploy: + deploy-prod: + name: Production runs-on: ubuntu-latest + environment: Production + if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Production') steps: - name: Executing remote SSH commands using SSH key - uses: appleboy/ssh-action@master + uses: appleboy/ssh-action@v1.0.3 + with: + username: ${{ secrets.USERNAME }} + host: ${{ secrets.HOST }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + cd ${GITHUB_REPOSITORY##*/} + git pull + docker compose down + docker compose up -d + + deploy-dev: + name: Development + runs-on: ubuntu-latest + environment: Development + if: github.ref == 'refs/heads/dev' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Development') + steps: + - name: Executing remote SSH commands using SSH key + uses: appleboy/ssh-action@v1.0.3 with: username: ${{ secrets.USERNAME }} host: ${{ secrets.HOST }} From 58164ccf0e51e270ddb4d8244d5380a3e23a7335 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:09:31 +0200 Subject: [PATCH 10/14] ci: checkout branch in deployment action --- .github/workflows/deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c77af87..13997b9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -29,6 +29,7 @@ jobs: port: ${{ secrets.PORT }} script: | cd ${GITHUB_REPOSITORY##*/} + git checkout ${GITHUB_REF##*/} git pull docker compose down docker compose up -d @@ -48,6 +49,7 @@ jobs: port: ${{ secrets.PORT }} script: | cd ${GITHUB_REPOSITORY##*/} + git checkout ${GITHUB_REF##*/} git pull docker compose down docker compose up -d From 6f798967e72c353288c71002b642664c1988c6f2 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:52:36 +0200 Subject: [PATCH 11/14] ci: move deployment script to its own file --- .github/workflows/deploy-script.yml | 38 ++++++++++++++++++++++ .github/workflows/deploy.yml | 50 +++++++++++------------------ 2 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/deploy-script.yml diff --git a/.github/workflows/deploy-script.yml b/.github/workflows/deploy-script.yml new file mode 100644 index 0000000..655ec36 --- /dev/null +++ b/.github/workflows/deploy-script.yml @@ -0,0 +1,38 @@ +name: SSH Deploy Script + +on: + workflow_call: + inputs: + environment: + required: true + type: string + branch: + required: true + type: string + secrets: + host: + required: true + port: + required: true + key: + required: true + username: + required: true + +jobs: + deploy: + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + steps: + - uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.host }} + port: ${{ secrets.port }} + key: ${{ secrets.key }} + username: ${{ secrets.username }} + script: | + cd ${GITHUB_REPOSITORY##*/} + git checkout ${{ inputs.branch }} + git pull + docker compose down + docker compose up -d diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 13997b9..d050155 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,40 +16,26 @@ on: jobs: deploy-prod: name: Production - runs-on: ubuntu-latest - environment: Production if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Production') - steps: - - name: Executing remote SSH commands using SSH key - uses: appleboy/ssh-action@v1.0.3 - with: - username: ${{ secrets.USERNAME }} - host: ${{ secrets.HOST }} - key: ${{ secrets.KEY }} - port: ${{ secrets.PORT }} - script: | - cd ${GITHUB_REPOSITORY##*/} - git checkout ${GITHUB_REF##*/} - git pull - docker compose down - docker compose up -d + uses: ./.github/workflows/deploy-script.yml + with: + environment: Production + branch: main + secrets: + host: ${{ secrets.ssh_host }} + port: ${{ secrets.ssh_port }} + key: ${{ secrets.ssh_key }} + username: ${{ secrets.username }} deploy-dev: name: Development - runs-on: ubuntu-latest - environment: Development if: github.ref == 'refs/heads/dev' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Development') - steps: - - name: Executing remote SSH commands using SSH key - uses: appleboy/ssh-action@v1.0.3 - with: - username: ${{ secrets.USERNAME }} - host: ${{ secrets.HOST }} - key: ${{ secrets.KEY }} - port: ${{ secrets.PORT }} - script: | - cd ${GITHUB_REPOSITORY##*/} - git checkout ${GITHUB_REF##*/} - git pull - docker compose down - docker compose up -d + uses: ./.github/workflows/deploy-script.yml + with: + environment: Development + branch: dev + secrets: + host: ${{ secrets.ssh_host }} + port: ${{ secrets.ssh_port }} + key: ${{ secrets.ssh_key }} + username: ${{ secrets.username }} From 2cfdcd854369689611d7b96d8b64a6dddab50a2f Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:55:37 +0200 Subject: [PATCH 12/14] ci: fix secret names for deploy script --- .github/workflows/deploy-script.yml | 3 ++- .github/workflows/deploy.yml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy-script.yml b/.github/workflows/deploy-script.yml index 655ec36..8fadd63 100644 --- a/.github/workflows/deploy-script.yml +++ b/.github/workflows/deploy-script.yml @@ -20,7 +20,8 @@ on: required: true jobs: - deploy: + script: + name: Script runs-on: ubuntu-latest environment: ${{ inputs.environment }} steps: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d050155..ce88086 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -22,10 +22,10 @@ jobs: environment: Production branch: main secrets: - host: ${{ secrets.ssh_host }} - port: ${{ secrets.ssh_port }} - key: ${{ secrets.ssh_key }} - username: ${{ secrets.username }} + host: ${{ secrets.HOST }} + port: ${{ secrets.PORT }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} deploy-dev: name: Development @@ -35,7 +35,7 @@ jobs: environment: Development branch: dev secrets: - host: ${{ secrets.ssh_host }} - port: ${{ secrets.ssh_port }} - key: ${{ secrets.ssh_key }} - username: ${{ secrets.username }} + host: ${{ secrets.HOST }} + port: ${{ secrets.PORT }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} From 915f1ece2d9e58530880ed6db0a94b260818464d Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:03:09 +0200 Subject: [PATCH 13/14] ci: add path variable --- .github/workflows/deploy-script.yml | 5 ++++- .github/workflows/deploy.yml | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-script.yml b/.github/workflows/deploy-script.yml index 8fadd63..3af2b08 100644 --- a/.github/workflows/deploy-script.yml +++ b/.github/workflows/deploy-script.yml @@ -9,6 +9,9 @@ on: branch: required: true type: string + path: + required: true + type: string secrets: host: required: true @@ -32,7 +35,7 @@ jobs: key: ${{ secrets.key }} username: ${{ secrets.username }} script: | - cd ${GITHUB_REPOSITORY##*/} + cd ${{ inputs.path }} git checkout ${{ inputs.branch }} git pull docker compose down diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ce88086..74009b9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,6 +21,7 @@ jobs: with: environment: Production branch: main + path: website-next secrets: host: ${{ secrets.HOST }} port: ${{ secrets.PORT }} @@ -34,6 +35,7 @@ jobs: with: environment: Development branch: dev + path: website-next secrets: host: ${{ secrets.HOST }} port: ${{ secrets.PORT }} From 055e6dc22aef308dcf0854063026c763b13a7682 Mon Sep 17 00:00:00 2001 From: Michael Brusegard <56915010+michaelbrusegard@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:11:58 +0200 Subject: [PATCH 14/14] ci: set restart policy for deployment --- .github/workflows/deploy-script.yml | 2 +- docker-compose.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-script.yml b/.github/workflows/deploy-script.yml index 3af2b08..38045f4 100644 --- a/.github/workflows/deploy-script.yml +++ b/.github/workflows/deploy-script.yml @@ -39,4 +39,4 @@ jobs: git checkout ${{ inputs.branch }} git pull docker compose down - docker compose up -d + docker compose up --build -d diff --git a/docker-compose.yml b/docker-compose.yml index 50e0d20..72d7891 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,7 @@ services: dockerfile: Dockerfile ports: - "3000:3000" + restart: unless-stopped db: image: postgres:16 environment: @@ -17,6 +18,7 @@ services: - ./data/db:/var/lib/postgresql/data ports: - "5432:5432" + restart: unless-stopped s3: image: bitnami/minio:2024 environment: @@ -27,3 +29,4 @@ services: - ./data/s3:/bitnami/minio/data ports: - "9000:9000" + restart: unless-stopped