Merge pull request #1189 from mikecao/dev

v1.32.0
This commit is contained in:
Mike Cao 2022-06-10 13:46:48 -07:00 committed by GitHub
commit 4f8bcb81d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 665 additions and 605 deletions

View File

@ -1,45 +1,52 @@
# Build image # Install dependencies only when needed
FROM node:12.22-alpine AS build FROM node:16-alpine AS deps
ARG BASE_PATH # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
ARG DATABASE_TYPE RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:16-alpine AS builder
ENV BASE_PATH=$BASE_PATH ENV BASE_PATH=$BASE_PATH
ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami"
ENV DATABASE_TYPE=$DATABASE_TYPE ENV DATABASE_TYPE=$DATABASE_TYPE
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
WORKDIR /build # Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn config set --home enableTelemetry 0
COPY package.json yarn.lock /build/
# Install only the production dependencies
RUN yarn install --production --frozen-lockfile
# Cache these modules for production
RUN cp -R node_modules/ prod_node_modules/
# Install development dependencies
RUN yarn install --frozen-lockfile
COPY . /build
RUN yarn next telemetry disable
RUN yarn build RUN yarn build
# Production image # Production image, copy all the files and run next
FROM node:12.22-alpine AS production FROM node:16-alpine AS runner
WORKDIR /app WORKDIR /app
# Copy cached dependencies ENV NODE_ENV production
COPY --from=build /build/prod_node_modules ./node_modules # Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1
# Copy generated Prisma client RUN addgroup --system --gid 1001 nodejs
COPY --from=build /build/node_modules/.prisma/ ./node_modules/.prisma/ RUN adduser --system --uid 1001 nextjs
COPY --from=build /build/yarn.lock /build/package.json ./ # You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=build /build/.next ./.next COPY --from=builder /app/next.config.js ./
COPY --from=build /build/public ./public COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
USER node # Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000 EXPOSE 3000
CMD ["yarn", "start"]
ENV PORT 3000
CMD ["node", "server.js"]

View File

@ -19,12 +19,18 @@ See [Running on Railway](https://umami.is/docs/running-on-railway) to get starte
- A server with Node.js 12 or newer - A server with Node.js 12 or newer
- A database (MySQL or Postgresql) - A database (MySQL or Postgresql)
### Install Yarn (if needed)
```
npm install -g yarn
```
### Get the source code and install packages ### Get the source code and install packages
``` ```
git clone https://github.com/mikecao/umami.git git clone https://github.com/mikecao/umami.git
cd umami cd umami
npm install yarn install
``` ```
### Create database tables ### Create database tables
@ -67,13 +73,13 @@ The `HASH_SALT` is used to generate unique values for your installation.
### Build the application ### Build the application
```bash ```bash
npm run build yarn build
``` ```
### Start the application ### Start the application
```bash ```bash
npm start yarn start
``` ```
By default this will launch the application on `http://localhost:3000`. You will need to either By default this will launch the application on `http://localhost:3000`. You will need to either
@ -104,8 +110,8 @@ To get the latest features, simply do a pull, install any new dependencies, and
```bash ```bash
git pull git pull
npm install yarn install
npm run build yarn build
``` ```
To update the Docker image, simply pull the new images and rebuild: To update the Docker image, simply pull the new images and rebuild:

View File

@ -32,7 +32,9 @@ export default function Dashboard() {
return ( return (
<Page> <Page>
<PageHeader> <PageHeader>
<div>Dashboard</div> <div>
<FormattedMessage id="label.dashboard" defaultMessage="Dashboard" />
</div>
<DashboardSettingsButton /> <DashboardSettingsButton />
</PageHeader> </PageHeader>
<WebsiteList websites={data} showCharts={showCharts} limit={max} /> <WebsiteList websites={data} showCharts={showCharts} limit={max} />

View File

@ -5,14 +5,14 @@ import useApi from './useApi';
export default function useFetch(url, options = {}, update = []) { export default function useFetch(url, options = {}, update = []) {
const [response, setResponse] = useState(); const [response, setResponse] = useState();
const [error, setError] = useState(); const [error, setError] = useState();
const [loading, setLoadiing] = useState(false); const [loading, setLoading] = useState(false);
const [count, setCount] = useState(0); const [count, setCount] = useState(0);
const { get } = useApi(); const { get } = useApi();
const { params = {}, headers = {}, disabled, delay = 0, interval, onDataLoad } = options; const { params = {}, headers = {}, disabled, delay = 0, interval, onDataLoad } = options;
async function loadData(params) { async function loadData(params) {
try { try {
setLoadiing(true); setLoading(true);
setError(null); setError(null);
const time = performance.now(); const time = performance.now();
@ -32,7 +32,7 @@ export default function useFetch(url, options = {}, update = []) {
console.error(e); console.error(e);
setError(e); setError(e);
} finally { } finally {
setLoadiing(false); setLoading(false);
} }
} }

View File

@ -51,7 +51,7 @@
"label.settings": "Einstellungen", "label.settings": "Einstellungen",
"label.share-url": "Freigabe-URL", "label.share-url": "Freigabe-URL",
"label.single-day": "Ein Tag", "label.single-day": "Ein Tag",
"label.theme": "Theme", "label.theme": "Thema",
"label.this-month": "Diesen Monat", "label.this-month": "Diesen Monat",
"label.this-week": "Diese Woche", "label.this-week": "Diese Woche",
"label.this-year": "Dieses Jahr", "label.this-year": "Dieses Jahr",
@ -92,7 +92,7 @@
"metrics.countries": "Länder", "metrics.countries": "Länder",
"metrics.device.desktop": "Desktop", "metrics.device.desktop": "Desktop",
"metrics.device.laptop": "Laptop", "metrics.device.laptop": "Laptop",
"metrics.device.mobile": "Mobiltelefon", "metrics.device.mobile": "Handy",
"metrics.device.tablet": "Tablet", "metrics.device.tablet": "Tablet",
"metrics.devices": "Geräte", "metrics.devices": "Geräte",
"metrics.events": "Ereignisse", "metrics.events": "Ereignisse",

View File

@ -6,6 +6,9 @@ module.exports = {
VERSION: pkg.version, VERSION: pkg.version,
}, },
basePath: process.env.BASE_PATH, basePath: process.env.BASE_PATH,
experimental: {
outputStandalone: true,
},
eslint: { eslint: {
ignoreDuringBuilds: true, ignoreDuringBuilds: true,
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "umami", "name": "umami",
"version": "1.31.0", "version": "1.32.0",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.", "description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Mike Cao <mike@mikecao.com>", "author": "Mike Cao <mike@mikecao.com>",
"license": "MIT", "license": "MIT",
@ -54,7 +54,7 @@
}, },
"dependencies": { "dependencies": {
"@fontsource/inter": "4.5.7", "@fontsource/inter": "4.5.7",
"@prisma/client": "3.12.0", "@prisma/client": "3.14.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"chalk": "^4.1.1", "chalk": "^4.1.1",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
@ -112,10 +112,10 @@
"postcss": "^8.4.12", "postcss": "^8.4.12",
"postcss-flexbugs-fixes": "^5.0.2", "postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"postcss-preset-env": "^7.4.2", "postcss-preset-env": "7.4.3",
"postcss-rtlcss": "^3.6.1", "postcss-rtlcss": "^3.6.1",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"prisma": "3.12.0", "prisma": "3.14.0",
"prompts": "2.4.2", "prompts": "2.4.2",
"rollup": "^2.70.1", "rollup": "^2.70.1",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",

View File

@ -24,7 +24,6 @@ const Intl = ({ children }) => {
export default function App({ Component, pageProps }) { export default function App({ Component, pageProps }) {
const { basePath } = useRouter(); const { basePath } = useRouter();
const { dir } = useLocale(); const { dir } = useLocale();
const version = process.env.VERSION;
return ( return (
<Intl> <Intl>
@ -35,12 +34,6 @@ export default function App({ Component, pageProps }) {
<link rel="icon" type="image/png" sizes="16x16" href={`${basePath}/favicon-16x16.png`} /> <link rel="icon" type="image/png" sizes="16x16" href={`${basePath}/favicon-16x16.png`} />
<link rel="manifest" href={`${basePath}/site.webmanifest`} /> <link rel="manifest" href={`${basePath}/site.webmanifest`} />
<link rel="mask-icon" href={`${basePath}/safari-pinned-tab.svg`} color="#5bbad5" /> <link rel="mask-icon" href={`${basePath}/safari-pinned-tab.svg`} color="#5bbad5" />
<link
rel="preload"
href={`https://i.umami.is/icon.png?v=${version}`}
as="image"
type="image/png"
/>
<meta name="msapplication-TileColor" content="#da532c" /> <meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#fafafa" media="(prefers-color-scheme: light)" /> <meta name="theme-color" content="#fafafa" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" /> <meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" />

View File

@ -17,7 +17,7 @@ function customScriptName(req) {
function disableLogin(req) { function disableLogin(req) {
if (process.env.DISABLE_LOGIN && req.nextUrl.pathname.endsWith('/login')) { if (process.env.DISABLE_LOGIN && req.nextUrl.pathname.endsWith('/login')) {
return new Response('403 Forbidden', { status: 403 }); return new Response('Login is disabled', { status: 403 });
} }
} }

View File

@ -334,7 +334,7 @@
"label.theme": [ "label.theme": [
{ {
"type": 0, "type": 0,
"value": "Theme" "value": "Thema"
} }
], ],
"label.this-month": [ "label.this-month": [
@ -704,7 +704,7 @@
"metrics.device.mobile": [ "metrics.device.mobile": [
{ {
"type": 0, "type": 0,
"value": "Mobiltelefon" "value": "Handy"
} }
], ],
"metrics.device.tablet": [ "metrics.device.tablet": [

View File

@ -4,7 +4,7 @@ import semver from 'semver';
import { VERSION_CHECK } from 'lib/constants'; import { VERSION_CHECK } from 'lib/constants';
import { getItem } from 'lib/web'; import { getItem } from 'lib/web';
const REPO_URL = 'https://api.github.com/repos/mikecao/umami/releases/latest'; const REPO_URL = 'https://api.umami.is/v1/updates';
const initialState = { const initialState = {
current: process.env.VERSION, current: process.env.VERSION,
@ -20,7 +20,7 @@ export async function checkVersion() {
const data = await fetch(REPO_URL, { const data = await fetch(REPO_URL, {
method: 'get', method: 'get',
headers: { headers: {
Accept: 'application/vnd.github.v3+json', Accept: 'application/json',
}, },
}).then(res => { }).then(res => {
if (res.ok) { if (res.ok) {
@ -36,9 +36,7 @@ export async function checkVersion() {
store.setState( store.setState(
produce(state => { produce(state => {
const { tag_name } = data; const { latest } = data;
const latest = tag_name.startsWith('v') ? tag_name.slice(1) : tag_name;
const lastCheck = getItem(VERSION_CHECK); const lastCheck = getItem(VERSION_CHECK);
const hasUpdate = latest && semver.gt(latest, current) && lastCheck?.version !== latest; const hasUpdate = latest && semver.gt(latest, current) && lastCheck?.version !== latest;

View File

@ -122,7 +122,11 @@ import { removeTrailingSlash } from '../lib/url';
payload, payload,
}); });
navigator.sendBeacon(`${root}/api/collect`, data); fetch(`${root}/api/collect`, {
method: 'POST',
body: data,
keepalive: true,
});
}; };
const addEvents = node => { const addEvents = node => {

1135
yarn.lock

File diff suppressed because it is too large Load Diff