Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dockerfile not working #647

Closed
wants to merge 4 commits into from
Closed

Fix dockerfile not working #647

wants to merge 4 commits into from

Conversation

zsnmwy
Copy link

@zsnmwy zsnmwy commented May 29, 2023

The origin Dockerfile is not working.


  1. Fix Dockerfile
  2. Support building Docker Image and push to GHCR.
  3. Support platforms: linux/amd64 linux/arm64

You can try docker run --rm -it -p 8077:80 ghcr.io/zsnmwy/esmd:latest.

@zsnmwy
Copy link
Author

zsnmwy commented May 29, 2023

Share My K8S Config.

apiVersion: v1
kind: ConfigMap
metadata:
  name: esm-config
  namespace: esm
data:
  config.json: |
    {
      "port": 80,
      "tlsPort": 0,
      "nsPort": 8088,
      "buildConcurrency": 0,
      "workDir": "~/.esmd",
      "cache": "memory:default",
      "database": "bolt:~/.esmd/esm.db",
      "storage": "local:~/.esmd/storage",
      "logDir": "~/.esmd/log",
      "logLevel": "debug",
      "origin": "https://esm.example.com",
      "basePath": "/",
      "npmRegistry": "https://registry.npmmirror.com/",
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: esm
  namespace: esm
  labels:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: esm
      app.kubernetes.io/name: esm
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: esm
        app.kubernetes.io/name: esm
    spec:
      containers:
        - name: esm
          image: change to your image
          volumeMounts:
            - name: config-volume
              mountPath: /home/esm/config.json
              subPath: config.json
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          resources: {}
          livenessProbe:
            httpGet:
              path: /
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      volumes:
        - name: config-volume
          configMap:
            name: esm-config
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext:
        runAsUser: 0
        runAsGroup: 0
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

---
apiVersion: v1
kind: Service
metadata:
  name: esm
  namespace: esm
  labels:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: http
  selector:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster

@ije
Copy link
Member

ije commented May 29, 2023

Share My K8S Config.

apiVersion: v1
kind: ConfigMap
metadata:
  name: esm-config
  namespace: esm
data:
  config.json: |
    {
      "port": 80,
      "tlsPort": 0,
      "nsPort": 8088,
      "buildConcurrency": 0,
      "workDir": "~/.esmd",
      "cache": "memory:default",
      "database": "bolt:~/.esmd/esm.db",
      "storage": "local:~/.esmd/storage",
      "logDir": "~/.esmd/log",
      "logLevel": "debug",
      "origin": "https://esm.example.com",
      "basePath": "/",
      "npmRegistry": "https://registry.npmmirror.com/",
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: esm
  namespace: esm
  labels:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: esm
      app.kubernetes.io/name: esm
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: esm
        app.kubernetes.io/name: esm
    spec:
      containers:
        - name: esm
          image: change to your image
          volumeMounts:
            - name: config-volume
              mountPath: /home/esm/config.json
              subPath: config.json
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          resources: {}
          livenessProbe:
            httpGet:
              path: /
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /
              port: http
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      volumes:
        - name: config-volume
          configMap:
            name: esm-config
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext:
        runAsUser: 0
        runAsGroup: 0
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

---
apiVersion: v1
kind: Service
metadata:
  name: esm
  namespace: esm
  labels:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: http
  selector:
    app.kubernetes.io/instance: esm
    app.kubernetes.io/name: esm
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster

thats great! does this handle clusters?

with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i need to put my own token for the CI right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to change it.
GitHub provides some contexts for each task.
See https://docs.github.com/en/actions/learn-github-actions/contexts

That will auto-login to your GHCR instance.


on:
push:
branches: [ "main" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just on tags like v124? because we may put bad code to the main branch

Copy link
Author

@zsnmwy zsnmwy May 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can.

But it's hard to debug if I do not have the repo permission.
I have no permission to push images to your GHCR instance.
Github action has strict permission.

I recommend you copy the action from my existing file.

It can auto-build images based on tag, branch, and pull requests.
And will auto-comment the result to PR if the action trigger comes from PR.

That tags will be like that.

The PR Comments

context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository_owner }}/esmd:latest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i prefer ghcr.io/owner/esm.sh instead of ghcr.io/owner/esmd, can you pls change?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't want to change it anymore.
It's hard for me to debug the code because of the action permission.
You can merge it first and change it.

RUN useradd -u 1000 -m esm
RUN mkdir /esm && chown esm:esm /esm
RUN git clone https://github.com/esm-dev/esm.sh /esm/esm.sh
RUN git checkout v124
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, let's use the latest tag instead of main branch

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/gocrane/crane/blob/9776243d8f37f2766fa7f39ffb4b2470de922857/.github/workflows/build-images.yml#L90C12-L95

Reading the version information from git is better than manual changes each time.

Comment on lines +15 to +19
RUN apk add --no-cache libc6-compat xz
RUN addgroup -g $GROUP_ID $GROUP_NAME && \
adduser --shell /sbin/nologin --disabled-password \
--uid $USER_ID --ingroup $GROUP_NAME $USER_NAME
RUN mkdir -p /usr/local/lib && chown -R $USER_NAME:$GROUP_NAME /usr/local
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wath is for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is prepared for non-root users.
Create a user and give the right permissions.

You must add the lib libc6-compat.
If not the server will crash.

WORKDIR /esm
RUN go build -o bin/esmd esm.sh/main.go
FROM node:18-alpine3.16
ENV USER_ID=65535
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondered, can we remove the USER_ID and GROUP_ID perm?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want the script to run as root, you can.

You can pass the -u 0:0 params to docker.
That will be run as root.

That full command is: docker run --rm -it -p 8077:80 -u 0:0 ghcr.io/zsnmwy/esmd:latest.

That's a security question.
See https://docs.docker.com/engine/security/rootless/

@zsnmwy
Copy link
Author

zsnmwy commented May 29, 2023

I have to say that the k8s share code is not enough to handle large service requests.
You should add HPA to enable the k8s autoscaling features.
However, HPA has inherent limitations due to design issues.
You can use EHPA to avoid that.
It's not easy for beginners. :)

ESM should support S3 and Redis.
S3 and Redis can help ESM share the status globally.

@ije
Copy link
Member

ije commented Sep 4, 2023

@ije ije closed this Sep 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants